Решил организовать очереди с потоками - выяснилось, что что-то не так. Поэтому упростил задачу, чтобы найти причину непонятки.
Есть счетчик counter, защищенный мьютексом counter_mutex.
Есть два потока, incrementor и decrementor. Первый увеличивает счетчик, второй - уменьшает, причем только до нуля, после чего ожидает сигнала от первого потока. Есть условная переменная cond, защищенная мьютексом cond_mutex. Поток incrementor после увеличения счетчика вызывает pthread_cond_signal(&cond). Я ожидал, что как только incrementor сигналит, decrementor просыпается, однако...
Вопрос: почему incrementor успевает увеличить счетчик очень много раз,
при этом столько же раз просигналив, а потом только decrementor просыпается, уменьшает счетчик до нуля и уже после этого откликается после каждого сигнала. Код прилагается.
#include <pthread.h>
pthread_mutex_t counter_mutex;
pthread_mutex_t cond_mutex;
pthread_cond_t cond;
pthread_t incrementor_thread;
pthread_t decrementor_thread;
int counter;
void* decrementor(void)
{
printf("decrementor(): called\n");
while(1)
{
while(1)
{
pthread_mutex_lock(&counter_mutex);
if(0 == counter)
{
/* nothing to decrement: suspend */
pthread_mutex_unlock(&counter_mutex);
break;
}
counter--;
pthread_mutex_unlock(&counter_mutex);
} /* inner loop */
pthread_mutex_lock(&cond_mutex);
printf("decrementor(): suspended\n");
pthread_cond_wait(&cond, &cond_mutex);
printf("decrementor(): wake up\n");
pthread_mutex_unlock(&cond_mutex);
} /* outer loop */
}
void* incrementor(void *p)
{
while(1)
{
printf("incrementor(): generating packet\n");
pthread_mutex_lock(&counter_mutex);
counter++;
printf("increment_counter(): counter=%d\n", counter);
pthread_mutex_unlock(&counter_mutex);
pthread_mutex_lock(&cond_mutex);
printf("register_packet(): signalling\n");
pthread_cond_signal(&cond);
pthread_mutex_unlock(&cond_mutex);
}
}
int main()
{
counter = 0;
pthread_mutex_init(&counter_mutex, NULL);
pthread_mutex_init(&cond_mutex, NULL);
pthread_cond_init(&cond, NULL);
pthread_create(&decrementor_thread, NULL, decrementor, NULL);
pthread_create(&incrementor_thread, NULL, incrementor, NULL);
/* loop forever */
while(1) {
sleep(10);
}
return 0;
}
Ответ на:
комментарий
от fghj
Ответ на:
комментарий
от fghj
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.
Похожие темы
- Форум Структура epoll сервера (2010)
- Форум Планирование потоков в NPTL (2007)
- Форум Реализовать последовательно-параллельный запуск потоков (2017)
- Форум pthread_cond_timedwait (2005)
- Форум Producer <-> Consumer (2008)
- Форум Как правильно синхронизировать потоки? (2009)
- Форум pthreads - ошибка линковки (2001)
- Форум Mutex и c++ (2012)
- Форум Переход от LinuxThreads к NTPL (2004)
- Форум Создание списка в gtk (2010)