Вопрос производителя / потребителя - PullRequest
0 голосов
/ 04 декабря 2010

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

Сначала я думал только о двух семафорах:

writeSemaphore, инициализированный 5, является семафором, который сообщает, разрешено ли записывающему устройству выполнять запись в буфер.когда он, наконец, опустится до 0, родительский процесс будет заблокирован до тех пор, пока один из потомков не разблокирует его (после прочтения какого-либо блока).

readSemaphore, инициализированный в 0, - это семафор, который сообщает, является лииз читателей разрешено читать из буфера.

Но теперь, когда я об этом думаю, это не помешало бы мне иметь 2 потребителя, обращающихся к общей памяти одновременно.Я должен предотвратить это.Поэтому я ввел третий семафор:

allowedToRead, который равен 1 или 0, который разрешает или блокирует доступ к дочерним процессам.

Вот псевдокод для дочерних и родительских процессов:

Ребенок:

while (something) {
    wait(readSemaphore)
    wait(allowedToRead)
    <<read from shared memory>>
    post(allowedToRead)
    post(writeSemaphore)
}

Родитель:

while (something) {
    wait(writeSemaphore)
    <<writes to shared memory>>
    post(allowedToRead)
}

Верны ли мои рассуждения?

Спасибо

Ответы [ 2 ]

1 голос
/ 07 декабря 2010

Хачик наполовину прав.С ним все может быть в порядке, но его описание не так ясно, как могло бы быть.

Во-первых, когда у вас есть родительский пост allowedToRead, вы, вероятно, хотите, чтобы он отправил readSemaphore.

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

В-третьих, я быиспользовал мьютекс вместо семафора для allowedToRead.

В-четвертых, что определяет, какой дочерний элемент читает, какие данные или он должен быть первым предоставлен первым, как свиньи в отстойном ведре?

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

1 голос
/ 04 декабря 2010

Нет.

  1. писатель должен освободить readSemaphore при записи одной единицы информации;
  2. писатель должен получить allowedToRead блокировку (семафор 0,1 - этоблокировка / мьютекс) перед записью в общую память, чтобы предотвратить состояние гонки.

Для упрощения: рассмотрим две функции read_shared_memory, write_shared_memory, которые предназначены для чтения и записи из / в общую память соответственнои оба получают / освобождают одну и ту же блокировку перед чтением / записью.

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

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

Википедия описывает это более научным способом:)

...