Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C++] Watek w klasie

Ostatnio zmodyfikowano 2017-07-30 13:16
Autor Wiadomość
jasiek1309
Temat założony przez niniejszego użytkownika
[C++] Watek w klasie
» 2017-07-25 01:53:54
Witam,
Nie wiem czy nie umiem wątków i klas czy mój kompilator coś kręci, liczę że ktoś coś pomoże ;)

C/C++
#include <iostream>
#include <thread>

class Bazowa
{
public:
    virtual ~Bazowa()
    {
        if( thread.joinable() )
             thread.join();
       
    }
   
    virtual void start() final // PS: Czy tak sie robi w ogóle? :p
    {
        thread = std::thread( task, this );
    }
   
private:
    virtual void task()
    {
        std::cout << "No Siema" << std::endl;
    }
   
    std::thread thread;
};

class Pochodna
    : public Bazowa
{
private:
    virtual void task()
    {
        std::cout << "Witam" << std::endl;
    }
};


int main()
{
    Pochodna p;
    p.start();
   
    std::cout << std::endl; // Gdy ta linia jest zakomentowana program działa troszeczke inaczej
   
    return 0;
}

Ogólnie chodzi o to że jak za wywołaniem metody start jest jeszcze coś poza return to wykonywana jest metoda task klasy pochodnej, a jak nie ma nic to klasy bazowej.

Prosze o wyjaśnienia i pretensje że nic nie umiem XD
P-163543
Monika90
» 2017-07-25 09:31:40
Jeżeli jeden wątek czyta z jakiegoś miejsca w pamięci (jakiejś zmiennej), a drugi wątek w tym samym czasie zapisuje w to samo miejsce (zmienia wartość tej zmiennej), to jest to tzw. data race, czyli niezdefiniowane zachowanie.
P-163545
Kinexity
» 2017-07-25 11:09:11
Pozwoliłem sobie nieco zmodyfikować kod i teraz zawsze działa tak samo (przynajmniej w VS2017):

C/C++
#include <iostream>
#include <thread>
using namespace std;

class Bazowa {
public:
    virtual ~Bazowa() {
        if( my_thread.joinable() )
             my_thread.join();
       
    }
    virtual void start() final {
        my_thread = thread([ & ]()->void { task(); } );
    }
private:
    virtual void task() {
        cout << "No Siema" << endl;
    }
    thread my_thread;
};

class Pochodna
    : public Bazowa
{
private:
    virtual void task() {
        cout << "Witam" << endl;
    }
};

int main() {
    Pochodna p;
    p.start();
    cout << endl;
    return 0;
}

Nie rozumiem dlaczego u ciebie ten kod przeszedł ->
thread = std::thread( task, this );
. W czym kompilowałeś?
P-163548
Monika90
» 2017-07-25 12:15:30

Nie rozumiem dlaczego u ciebie ten kod przeszedł -> thread = std::thread( task, this );
. W czym kompilowałeś?

Wygląda na to że kompilator którego używa kolega jasiek1309 ma jakieś dziwne niestandardowe zachowanie, poprawnie powinno być tam
thread = std::thread( & Bazowa::task, this );


Ale to nie zmienia faktu że program ma data race, Twój też, kolego Kinexity, z tego samego powodu.
P-163550
Kinexity
» 2017-07-25 12:41:21
Data race występuje w obiekcie std::cout?

EDIT: Jak nie tam to gdzie?
P-163552
Monika90
» 2017-07-25 14:04:37
Nie.
P-163555
Monika90
» 2017-07-25 18:30:15
Destruktor w wątku głównym zmienia wskaźnik do tablicy funkcji wirtualnych, a drugi wątek używa tego wskaźnika by zadecydować którą wersję funkcji task wywołać.
P-163558
jasiek1309
Temat założony przez niniejszego użytkownika
» 2017-07-25 21:21:51
Czyli w jaki sposób to naprawić?
P-163563
« 1 » 2
  Strona 1 z 2 Następna strona