Как использовать очередь с двумя потоками - один для потребителя и один для производителя - PullRequest
0 голосов
/ 13 марта 2009

Я использую приложение, в котором приложение более низкого уровня всегда вызывает функцию обратного вызова RecData (char * buf) при получении данных.

В обратном вызове я создаю два потока и передаю функции потребителя и производителя этим созданным потокам соответственно.

Мой код:

void RecData (char * buf) {

CreateThread(NULL,0,producer_queue,(void *)buf,0,NULL);
CreateThread(NULL,0,consumer_queue,NULL,0,NULL);

}

Вышеуказанное работает, когда я получаю по одной информации за раз. Если я получаю, скажем, 5 данных почти в одно и то же время, то файл generator_queue должен сначала поместить все данные в очередь, а затем customer_queue должен начать извлекать данные, но здесь, как только производитель_строк помещает первые данные в очередь, consumer_queue получает их.

Ответы [ 2 ]

1 голос
/ 13 марта 2009

Я считаю, что вы хотите контролировать доступ к очереди. Вы захотите использовать мьютекс для управления чтением из очереди.

Когда вы получаете данные, вы блокируете мьютекс, затем ставите в очередь данные. Когда вы закончите ставить данные в очередь, снимите блокировку.

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

Этот подход может создать потенциальные тупики. Если ваш поток записи умирает до снятия блокировки, то ваш поток чтения не сможет продолжить (тогда снова ваш поток смерти может просто вызвать состояние ошибки).

Надеюсь, это имеет смысл.

0 голосов
/ 13 марта 2009

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

Проверьте ссылку ниже, как вы можете самостоятельно создать переменную условия в Windows: http://www.cs.wustl.edu/~schmidt/win32-cv-1.html

Если вы используете Windows Vista, вам может помочь приведенный ниже пример msdn: http://msdn.microsoft.com/en-us/library/ms686903(VS.85).aspx

Во всех случаях используйте логику, показанную на веб-сайте Шмидта, так как она выглядит более переносимой (о, да, переносимая в разных версиях Windows по крайней мере) Реализация Шмидта дает вам стандарт API POSIX, который широко используется в большинстве современных систем UNIX / LINUX.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...