Как избежать нескольких писателей в именованном канале?

Я пишу программу с именованным каналом с несколькими читателями и несколькими писателями. Идея состоит в том, чтобы использовать этот именованный канал для создания пар чтения/записи. Это:

  • А читает трубку
  • Б пишет в трубу (наоборот)
  • Пара А-Б создана!

Чтобы гарантировать, что только один процесс читает, а другой пишет, я использовал 2 блокировки с помощью flock. Именно так.

Код считывателя:

echo "[JOB $2, Part $REMAINING] Taking next machine..."
    VMTAKEN=$((
    flock -x 200;
    cat $VMPIPE;
    )200>$JOINQUEUELOCK)

echo "[JOB $2, Part $REMAINING] Machine $VMTAKEN taken..."

Код писателя:

((
flock -x 200;
echo "[MACHINE $MACHINEID] I am inside the critical section"
echo "$MACHINEID" > $VMPIPE;
    echo "[MACHINE $MACHINEID] Going outside the critical section"
)200>$VMQUEUELOCK)

echo "[MACHINE $MACHINEID] Got new Job"

У меня иногда возникает следующая проблема:

[MACHINE 3] I am inside the critical section
[JOB 1, Part 249] Taking next machine...
[MACHINE 3] Going outside the critical section
[MACHINE 1] I am inside the critical section
[MACHINE 1] Going outside the critical section
[MACHINE 1]: Got new Job
[MACHINE 3]: Got new Job
[JOB 1, Part 249] Machine 3
1 taken...

Как видите, Другой писатель написал до того, как читатель закончил читать. Что я могу сделать, чтобы избавиться от этой проблемы? Должен ли я использовать ACK Pipe или что-то в этом роде?

заранее спасибо


person Javier J. Salmeron Garcia    schedule 29.12.2010    source источник
comment
Какова семантика команды flock? Какой файл он блокирует? Кто это написал? Вы уверены, что он делает то, что должен делать? (Я могу найти справочные страницы только для вызова функции flock(), а не для команды, обертывающей его.)   -  person Jonathan Leffler    schedule 29.12.2010
comment
Похоже проблема не в флоке, а в записи в именованный канал. Как видно из вывода, две машины не находятся в критической секции одновременно.   -  person Javier J. Salmeron Garcia    schedule 29.12.2010


Ответы (1)


Это было бы типичным использованием семафоров:

  1. Создайте 2 семафора - один для чтения процессов, другой для процессов записи. установить для каждого семафора значение 1

  2. Чтение обрабатывает sem_wait(2) на семафоре для читателей до тех пор, пока семфора > 0, и понижает его до нуля, если они получают его.

  3. Процессы записи сделают то же самое с предназначенным для них семафором

  4. Управляющий процесс (который также может изначально настроить семафоры) может проверить, равны ли оба семафора нулю, и назначить пару

  5. считыватель/запись освобождает семафоры (снова увеличивая их на 1), поэтому следующий читатель или записывающий получит семафор.

Для передачи информации между читателем/писателем может использоваться разделяемая память...

person ktf    schedule 16.09.2011