Autor Wątek: boost conditional variable  (Przeczytany 882 razy)

Offline gawron89

  • Użytkownik

# Lipiec 25, 2014, 10:46:00
witam, mam problem z takim kodem

using namespace boost;

condition_variable cond;
mutex m;

void func()
{
this_thread::sleep(posix_time::seconds(4));
cond.notify_one();
}

int main()
{
for(;;)
{
thread t(func);
mutex::scoped_lock lock(m);
if(cond.wait_for(lock, chrono::seconds(2)) == cv_status::timeout)
{
std::cout << "timeout\n";
}
else
{
std::cout << "error\n";
}
t.join();
}
return 0;
}

watek główny jest blokowany az drugi watek wywoła notify_one() lub miną 2 sekundy. drugi watek ustawiony jest na 4 sekundy, wiec cond.wait_for według mnie zawsze powinno zwracać timeout, natomiast wartość zwracana jest dosłownie losowa, raz timeout a następnym razem nie, wypisuje error ~7 na 10 razy. co tu zmienić by to działało?


Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Xirdus

  • Redaktor

# Lipiec 25, 2014, 11:18:11
Nie rozumiesz wielowątkowości. Jak masz więcej niż jeden wątek, nie masz żadnej gwarancji, kiedy i w jakiej kolejności się one wykonają - wszystko zależy od systemowego schedulera. No i jest taka sprawa, że funkcja sleep() usypia wątek na co najmniej podany czas - tzn. jak masz pecha to wątek może wstać ponownie nawet wielokrotnie później. Raczej nie powinno się to zdarzyć, ale teoretycznie jest to jak najbardziej możliwe.

Ilurdzeniowy masz procesor?

Offline gawron89

  • Użytkownik

# Lipiec 25, 2014, 11:59:47
to co opisujesz występuje tylko na poziomie kilkuset milisekund a nie kilku sekund. w moim głównym programie zdarza się ze func() w ogolę nie wywołuje notify_one() a cond.wait_for zwraca po ustalonych 30 sekundach no_timeout, no cos jest nie tak.
wiec albo uzywam wait_for zle, np potrzebna jest jakas petla (na necie nie ma żadnych przykładów użycia wait_for z pętla), albo implementacja boosta ma jakis błąd.


edit:
dobra, w samej dokumentacji znalazłem ze wait_for może przekłamywać jeśli chodzi o zwracaną wartość, nie obejdzie się więc bez funkcji pomocniczej, to jest chyba poprawny kod
using namespace boost;

condition_variable cond;
mutex m;
bool done = 0;

bool need_continue()
{
return done;
}

void func()
{
this_thread::sleep_for(chrono::seconds(4));
done = 1;
cond.notify_one();
}

int main()
{
for(;;)
{
done = 0;
thread t(func);
mutex::scoped_lock lock(m);
if(!cond.wait_until(lock, chrono::system_clock::now() +
chrono::seconds(2), need_continue))
{
std::cout << "timeout\n";
}
else
{
std::cout << "no_timeout\n";
}
t.join();
}
return 0;
}
« Ostatnia zmiana: Lipiec 25, 2014, 13:57:44 wysłana przez gawron89 »