Использование двоичных семафоров в качестве счетного семафора - PullRequest
2 голосов
/ 04 апреля 2011

Я работаю над проектом, в котором решена проблема чтения и записи.
Мы должны использовать двоичные семафоры в качестве счетного семафора.
Мне запрещено использовать semget / semop / semctl.
Сначалакак мне объявить семафор?Я хочу использовать S и V в качестве имен семафоров.
Я собираю эту программу на c ++ и запускаю ее в unix.(g ++)

ADD ON: класс предоставляет один счетный семафор с методами:

  • waitSemaphore: если значение> 0 разблокирует, иначе блокирует
  • signalSemaphore: уменьшать семафорзначение на 1
  • deleteSemaphore: удаляет семафор
  • Используйте класс myCountingSemaphoreUsingBinarySemaphore для решения проблемы чтения-записи
  • readerCount должен быть глобальной целочисленной переменной.
  • Читатели читают это.
  • Writer обновляет его, добавляя 10 к предыдущему значению.
  • Средство чтения / записи обрабатывает значение базы данных (до / после).
  • Не использовать какие-либо из обычных (считающих) примитивов семафоров, таких как semget / semop / semctl, так как это те, которые вы моделируете, используя двоичный семафор.

Ответы [ 2 ]

1 голос
/ 04 апреля 2011

Исходя из этого, вы должны создать свой собственный класс семафоров. Вы можете иметь закрытую переменную-член для увеличения / уменьшения, как с семафором, и иметь двоичный закрытый член-семафор, чтобы сделать эти увеличения / уменьшения атомарными. Есть релиз / приобретение публичных методов, которые будут делать inc / dec. Когда счетчик обнулится, освободите двоичный семафор и дождитесь условия (другого мьютекса). Когда другой поток вызывает метод release для вашего класса семафоров, а значение счетчика теперь выше нуля, подайте сигнал всем тем, кто ожидает выполнения условия, и попытайтесь повторно получить ваш семафор.

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

0 голосов
/ 04 апреля 2011

Как отметил @Addander Kondratskiy, похоже, что вы должны использовать двоичный семафор для реализации настоящего семафора.Вот часть реализации Sempahore из одного из моих личных проектов, вам все еще нужно заполнить пробелы ...


#ifndef SEMAPHORE_20100517_H_
#define SEMAPHORE_20100517_H_

#include <Scheduler.h>
#include <queue>

class Semaphore {
public:
    explicit Semaphore(int count);

public:
    void wait();
    void signal();

private:
    void block();
    void unblock();

private:
    int                           value_;
    std::queue<scheduler::thread> waitlist_;
    mutex                         mutex_;
};

#endif

Semaphore::Semaphore(int count) : value_(count) {
    assert(count >= 0);
}

void Semaphore::wait() { // same as your P()

    mutex_.lock();

    if(--value_ < 0) {
        mutex_.unlock(); // we have to give up the lock if we are going to block
        block();
        mutex_.lock(); // reacquire the lock for symmetry when we exit
    }

    mutex_.unlock();
}

void Semaphore::signal() { // same as your V()

    mutex_.lock(); 

    if(++value_ <= 0) {
        unblock();
    }

    mutex_.unlock();
}

void Semaphore::block() {
    // Fill in the blanks!
    // block the current thread and add it to the queue!
}

void Semaphore::unblock() {
    // Fill in the blanks!
    // pull someone from the queue and unblock them!
}
...