DejaVu Temat założony przez niniejszego użytkownika |
[boost] Odpowiednik WaitForSingleObject » 2009-11-08 17:51:46 Poszukuję odpowiednika Wondowsowego WaitForSingleObject w bibliotece boost. Zastanawiam się czego użyć i jak użyć, żeby uzyskać taki efekt. Ktoś coś wie w tym temacie? |
|
Elaine |
» 2009-11-08 18:20:16 Metoda join()? |
|
DejaVu Temat założony przez niniejszego użytkownika |
» 2009-11-08 18:28:17 Nie chodzi mi o synchronizację wątków... chodzi mi o osobny mechanizm do czekania. Dokładniej: jeśli kolejka pusta to wstrzymaj pracę i czekaj na dane. |
|
Elaine |
» 2009-11-08 18:41:11 Poczytaj w dokumentacji np. o condition variables. Na przyszłość mów, o co konkretnie chodzi. WaitForSingleObject działa na kilku różnych rodzajach obiektów... |
|
DejaVu Temat założony przez niniejszego użytkownika |
» 2009-11-08 19:11:45 Ok, dzięki za pomoc. Walczyłem już wcześniej z tym ale nie oprogramowałem jednego przypadku i mi się krzaczyło. Problem powyżej opisany jest w przykładach boosta. Zmienna, która jest za to odpowiedzialna to buffer_not_empty.
#include <iostream> #include <vector> #include <boost/utility.hpp> #include <boost/thread/condition.hpp> #include <boost/thread/thread.hpp>
class bounded_buffer : private boost::noncopyable { public: typedef boost::mutex::scoped_lock lock; bounded_buffer( int n ) : begin( 0 ) , end( 0 ) , buffered( 0 ) , circular_buf( n ) { } void send( int m ) { lock lk( monitor ); while( buffered == circular_buf.size() ) buffer_not_full.wait( lk ); circular_buf[ end ] = m; end =( end + 1 ) % circular_buf.size(); ++buffered; buffer_not_empty.notify_one(); } int receive() { lock lk( monitor ); while( buffered == 0 ) buffer_not_empty.wait( lk ); int i = circular_buf[ begin ]; begin =( begin + 1 ) % circular_buf.size(); --buffered; buffer_not_full.notify_one(); return i; } private: int begin, end, buffered; std::vector < int > circular_buf; boost::condition buffer_not_full, buffer_not_empty; boost::mutex monitor; };
bounded_buffer buf( 2 );
boost::mutex io_mutex;
void sender() { int n = 0; while( n < 100 ) { buf.send( n ); { boost::mutex::scoped_lock io_lock( io_mutex ); std::cout << "sent: " << n << std::endl; } ++n; } buf.send( - 1 ); }
void receiver() { int n; do { n = buf.receive(); { boost::mutex::scoped_lock io_lock( io_mutex ); std::cout << "received: " << n << std::endl; } } while( n != - 1 ); }
int main( int, char *[] ) { boost::thread thrd1( & sender ); boost::thread thrd2( & receiver ); thrd1.join(); thrd2.join(); return 0; }
|
|
DejaVu Temat założony przez niniejszego użytkownika |
» 2010-01-16 02:01:01 Ostatnio trochę intensywniej programuję wielowątkowo i niestety muszę stwierdzić, że boost::condition działa zupełnie inaczej niż WaitForSingleObject(). Przykładowo: Thread 1: boost::mutex::scoped_lock lock( m_cs ); m_cond.wait( m_cs ); Thread 2: boost::mutex::scoped_lock lock( m_cs ); m_cond.notify_one(); Jeśli wykona się najpierw Thread 2, a następnie Thread 1 to Thread 1 będzie wisiał. W przypadku WaitForSingleObject ustawia się flagę czy ma przepuszczać czy nie, tak więc działa to zupełnie inaczej. Ponawiam więc pytanie postawione w temacie :) |
|
Elaine |
» 2010-01-16 12:37:50 To WaitForSingleObject przyjmuje jakieś flagi? Ja zawsze myślałem, że tylko uchwyt i czas czekania... Nie działa inaczej - to ty wywołujesz złą metodę. Zainteresuj się timed_wait(). |
|
DejaVu Temat założony przez niniejszego użytkownika |
» 2010-01-16 14:28:38 Nie jest istotne to jakie argumenty przyjmuje funkcja, tylko jak działa. MSDN: WaitForSingleObject - Waits until the specified object is in the signaled state or the time-out interval elapses. |
Nawiązując do boost'a timed_wait() działa tak samo jak wait() z tą różnicą, że można podać czas. Chodzi o permanentne ustawienie stanu 'signaled' lub 'nonsignaled', a nie automatyczne przełączanie na chwilę by zdjąć jakąś blokadę. boost::condition działa właśnie tak, że wysyła powiadomienie 'odblokuj' i zaraz po odblokowaniu blokuje ponownie, co jest nieporządane w moim przypadku. /edit: Mógłbym zrobić sobie rozwiązanie na WaitForSingleObject() ale wydaje mi się, że taka funkcjonalność powinna być dostępna w bibliotece boost... to są przecież podstawy. |
|
« 1 » 2 |