Один производитель, два потребителя и использование pthread_cond_signal & pthread_mutex_lock - PullRequest
2 голосов
/ 26 июня 2010

Я довольно новичок в программировании и пытаюсь разобраться с cond_signal & mutex_lock. Я пишу пример программы, в которой есть Один поток производителя и Два потока пользователя .

Существует очередь между производителем и первым потребителем и другая очередь между производителем и вторым потребителем. Мой производитель в основном является коммуникационным интерфейсом, который считывает пакеты из сети и на основе настроенного фильтра доставляет пакеты любому из потребителей.

Я пытаюсь использовать pthread_cond_signal & pthread_mutex_lock следующим образом между производителем и потребителем.

[У производителя]

0) Дождаться прибытия пакетов

1) Заблокировать мьютекс pthread_mutex_lock(&cons1Mux)

2) Добавить пакет в конец очереди потребителя

3) Сигнал потребителя 1 процесса pthread_cond_signal(&msgForCons1)

4) Разблокировать мьютекс pthread_mutex_lock(&cons1Mux)

5) Перейти к шагу 0

[У потребителя]

1) Блокировка мьютекса pthread_mutex_lock(&cons1Mux)

2) Ждать сигнала pthread_cond_wait(&msgForCons1,&cons1Mux)

3) После пробуждения прочитайте пакет

4) Удалить из очереди.

5) Разблокировать мьютекс pthread_mutex_unlock(&cons1Mux)

6) Перейти к шагу 1

Правильны ли вышеуказанные шаги? Если переключение происходит из потока потребителя точно после шага 5 в поток производителя, тогда возможно, что производитель может сигнализировать, что пакет ожидает, даже если потребитель еще не начал слушать этот сигнал. Это вызовет «пропущенный сигнал»?

Есть ли другие проблемы с этими шагами?

1 Ответ

1 голос
/ 27 июня 2010

Да, вы правы, у вас может быть проблема: если нет ожидающих потоков, pthread_cond_signal - это запрет.Он не находится где-то в очереди, чтобы вызвать последующее ожидание.

Что вы должны сделать, так это, для потребителя, после того, как вы приобрели мьютекс, проверьте, есть ли какая-либо работа, которую нужно сделать.Если есть, у вас есть мьютекс;взять на себя ответственность, обновить состояние и сделать это.Вам нужно только подождать, если нечего делать.

Канонический пример:

decrement_count() 
   { pthread_mutex_lock(&count_lock); 

     while (count == 0) 
        pthread_cond_wait(&count_nonzero, &count_lock); 
     count = count - 1; 
     pthread_mutex_unlock(&count_lock); 
   } 

increment_count() 
   { pthread_mutex_lock(&count_lock); 
     if (count == 0)
       pthread_cond_signal(&count_nonzero); 
     count = count + 1;
     pthread_mutex_unlock(&count_lock); 
    }

Обратите внимание, что убывающий поток «потребителя» не ждет, если есть что уменьшить,Шаблон одинаково хорошо применим к случаю, когда счетчик заменяется размером очереди или допустимостью структуры, содержащей сообщение.

...