Обычные реализации рабочей очереди, которые я видел, включают взаимные исключения и условные переменные.
Потребитель:
A) Acquires Lock
B) While Queue empty
Wait on Condition Variable (thus suspending thread and releasing lock)
C) Work object retrieved from queue
D) Lock is released
E) Do Work
F) GOTO A
Производитель:
A) Acquires Lock
B) Work is added to queue
C) condition variable is signaled (potentially releasing worker)
D) Lock is released
Я просматривал некоторый код и увидел реализацию, использующую каналы POSIX (раньше я не видел эту технику).
Потребитель:
A) Do select on pipe (thus suspending thread while no work)
B) Get Job from pipe
C) Do Work
D) GOTO A
Производитель:
A) Write Job to pipe.
Поскольку производитель и потребитель являются потоками внутри одного и того же приложения (таким образом, они совместно используют одно и то же адресное пространство и, следовательно, указатели между ними являются действительными); задания записываются в канал как адрес рабочего объекта (объект C ++). Поэтому все, что нужно записать / прочитать из канала, это 8-байтовый адрес.
Мой вопрос:
- Является ли это обычной техникой (защищен ли я от этого) и каковы преимущества / недостатки?
Мое любопытство было задето, потому что техника трубы не включает никаких видимых блокировок или сигналов (они могут быть скрыты в избранном). Поэтому мне было интересно, будет ли это более эффективным?
Edit:
Основано на комментариях в ответе Максима Егорушкина.
На самом деле «продюсер» в этом сценарии участвует в большом количестве операций ввода-вывода из большого количества параллельных источников. Поэтому я подозреваю, что первоначальный автор очень хотел, чтобы этот поток не блокировал ни при каких обстоятельствах, но также не хотел высокой стоимости работы в потоке «Производитель».