Mam problem z pthreads, gdzie myślę, że dostaję impasu. Stworzyłem kolejkę blokującą, która moim zdaniem działała, ale po wykonaniu kilku testów odkryłem, że jeśli spróbuję anulować wiele wątków blokujących blokowanie, wydaje się, że dostaję zakleszczenia.C5 pthread blokowanie kolejka impasu (myślę)
Kolejka blokowanie jest bardzo prosty i wygląda następująco:
template <class T> class Blocking_Queue
{
public:
Blocking_Queue()
{
pthread_mutex_init(&_lock, NULL);
pthread_cond_init(&_cond, NULL);
}
~Blocking_Queue()
{
pthread_mutex_destroy(&_lock);
pthread_cond_destroy(&_cond);
}
void put(T t)
{
pthread_mutex_lock(&_lock);
_queue.push(t);
pthread_cond_signal(&_cond);
pthread_mutex_unlock(&_lock);
}
T pull()
{
pthread_mutex_lock(&_lock);
while(_queue.empty())
{
pthread_cond_wait(&_cond, &_lock);
}
T t = _queue.front();
_queue.pop();
pthread_mutex_unlock(&_lock);
return t;
}
priavte:
std::queue<T> _queue;
pthread_cond_t _cond;
pthread_mutex_t _lock;
}
Do testowania Stworzyłem 4 wątki, które ciągnąć na tej kolejki blokującej. Dodałem kilka instrukcji drukowania do kolejki blokującej, a każdy wątek przechodzi do metody pthread_cond_wait(). Jednak gdy próbuję wywołać pthread_cancel() i pthread_join() w każdym wątku program po prostu się zawiesi.
Testowałem to również z jednym tylko wątkiem i działa idealnie.
Zgodnie z dokumentacją, pthread_cond_wait() jest punktem anulowania, więc wywołanie cancel na tych wątkach powinno spowodować, że przestaną wykonywać (i to działa tylko z jednym wątkiem). Jednak pthread_mutex_lock nie jest punktem anulowania. Czy coś może się zdarzyć w czasie, gdy zostanie wywołana funkcja pthread_cancel(), anulowany wątek pobiera muteks przed zakończeniem i nie odblokowuje go, a następnie, gdy następny wątek zostanie anulowany, nie może uzyskać dostępu do muteksu i zakleszczeń? Czy jest coś jeszcze, co robię źle.
Każda rada byłaby piękna. Dzięki :)
Spróbuj użyć [Helgrind] (http://valgrind.org/info/tools.html#helgrind), to była przydatna w przeszłości dla mnie do wykrywania warunków wyścigu i zakleszczeń. – Flexo
Anulowanie może być zdradzieckie. Pokaż nam więcej swojej logiki: jaki jest stan anulowania wątków roboczych?Jakie programy do sprzątania? I dokładnie w jaki sposób sekwencjonujesz połączenia, aby anulować/dołączyć do wielu wątków? – pilcrow