Производитель-потребитель создает 2 элемента Семафоры POSIX

3 потребителя 2 производителя. Чтение и запись в один буфер. Производитель A помещает 1 элемент в буфер (длина N), а производитель B помещает 2 элемента в буфер. Нет активного ожидания. Я не могу использовать семафоры System V.

Пример кода для производителя A:

void producerA(){
  while(1){
    sem_wait(full);
    sem_wait(mutex);

    Data * newData = (Data*) malloc(sizeof(Data));
    newData->val = generateRandomletter();
    newData->A = false;
    newData->B = false;
    newData->C = false;

    *((Data*) mem+tail) = *newData;

    ++elements;
    tail = (tail + 1) % N;

    sem_post(mutex); 
    sem_post(empty);
  }
}

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

sem_wait(full); sem_wait(full);

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

Какими способами я могу решить эту проблему?


person Aaroneiros    schedule 03.12.2016    source источник
comment
Переменные условия кажутся мне техникой, которая вам нужна.   -  person Mark Setchell    schedule 03.12.2016
comment
Поскольку у меня не может быть активного ожидания в процессе, это означает, что я не могу проверять условие на каждой итерации цикла. И если у вас есть что-то умнее, я был бы признателен.   -  person Aaroneiros    schedule 03.12.2016
comment
Весь смысл условных переменных в том, что они избегают активного ожидания.   -  person Mark Setchell    schedule 03.12.2016
comment
Ok. Я неправильно понял. Спасибо посмотрю.   -  person Aaroneiros    schedule 03.12.2016


Ответы (1)


https://gist.github.com/RobPiwowarek/65cb9896c109699c70217ba014b9ed20 Это было бы решением всей проблема у меня была.

TLDR: самая простая синхронизация, которую я могу обеспечить, — это использование семафоров full и empty для представления количества элементов, которые я поместил в буфер. Однако такое решение не работает для семафоров POSIX, если у меня есть производитель, который создает 2 элемента.

Мое решение основано на другой концепции.
Схема процесса сводится к следующему:

while(1){  
    down(mutex);
    size = get size
    if (condition related to size based on what process this is)
    {
         do your job;
         updateSize(int diff); // this can up() specific semaphores 
                               // based on size
                               // each process has his own semaphore
         up(mutex);
    }
    else 
    {
         up(mutex);
         down(process's own semaphore);
         continue;
    }
}

Я надеюсь, что это будет полезно для кого-то в будущем.

person Aaroneiros    schedule 04.12.2016