2015-07-02 6 views
1

Я читаю о Семафорах. Из того, что я понимаю, является то, что Семафор допускает доступ только к определенному количеству потоков для определенного ресурса. Я столкнулся с этим post, в котором объясняется, как создать простой класс семафора с использованием переменных условий и мьютекса. Код для облегчения доступа наклеивается сюда из этой ссылкеКак использовать следующий код Семафора

#include <mutex> 
#include <condition_variable> 

class Semaphore { 
public: 
    Semaphore (int count_ = 0) 
     : count(count) {} 

    inline void notify() 
    { 
     std::unique_lock<std::mutex> lock(mtx); 
     count++; 
     cv.notify_one(); 
    } 

    inline void wait() 
    { 
     std::unique_lock<std::mutex> lock(mtx); 

     while(count == 0){ 
      cv.wait(lock); 
     } 
     count--; 
    } 

private: 
    std::mutex mtx; 
    std::condition_variable cv; 
    int count; 
}; 

Мой вопрос состоит в том, как бы я использовать выше класс, чтобы сделать этот метод доступен только 3 потоков одновременно

void SomeFunction 
{ 
    ------------------------------> Only 3 threads should be allowed access to this function concurrently 
    int a = getSomeValue(); 
    //Do something useful 
    ------------------------------> 
} 

Я нахожусь думая, что я хотел бы сделать что-то вроде этого

Semaphore s(3); 
    void SomeFunction 
    { 
     s.wait(); 
     int a = getSomeValue(); 
     //Do sometning useful 
     s.notify(); 
    } 

Однако я не уверен, когда wait() и notify() будет называться?

ответ

2

Было бы лучше использовать RAII idiom семафора:

class SemaphoreLock 
{ 
public: 
    SemaphoreLock(Semaphore& s) 
     : _pS(&s) 
    { 
     _pS->wait(); 
    } 
    ~SemaphoreLock() 
    { 
     _pS->notify(); 
    } 
private: 
    Semaphore* _pS; 
}; 

Semaphore s(3); 
void SomeFunction() 
{ 
    SemaphoreLock sl(s); 
    // implement the function here 
} 

Если SemaphoreLock объект объявлен в самом начале тела функции, то wait() будет называться при входе в функцию и notify() бы вызывать непосредственно перед выходом из функции, также в случае, если выбрано исключение, а разматывание стека не прекращается.

Даже лучшее решение может быть в переименовании методов Семафора: wait в lock и notify в unlock. В этом случае можно было бы использовать std::lock_guard<Semaphore> вместо самонаписанного класса SemaphoreLock.

Смежные вопросы