C+0x没有信号量?如何同步线程?

C+0x没有信号量?如何同步线程?

C+0x真的没有信号量吗?关于堆栈溢出,已经有一些关于使用信号量的问题。我一直使用它们(POSIX信号量)让线程在另一个线程中等待某个事件:

void thread0(...){
  doSomething0();

  event1.wait();

  ...}void thread1(...){
  doSomething1();

  event1.post();

  ...}

如果我用互斥物做这个的话:

void thread0(...){
  doSomething0();

  event1.lock(); event1.unlock();

  ...}void thread1(...){
  event1.lock();

  doSomethingth1();

  event1.unlock();

  ...}

问题:它很难看,不能保证线程1先锁互斥锁(考虑到同一个线程应该锁定和解锁互斥对象,您也不能在线程0和线程1启动之前锁定事件1)。

那么,既然Boost也没有信号量,那么实现上述目标的最简单方法是什么呢?


慕桂英3389331
浏览 576回答 3
3回答

慕村225694

您可以通过互斥和条件变量轻松地构建一个:#include&nbsp;<mutex>#include&nbsp;<condition_variable>class&nbsp;semaphore{private: &nbsp;&nbsp;&nbsp;&nbsp;std::mutex&nbsp;mutex_; &nbsp;&nbsp;&nbsp;&nbsp;std::condition_variable&nbsp;condition_; &nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;long&nbsp;count_&nbsp;=&nbsp;0;&nbsp;//&nbsp;Initialized&nbsp;as&nbsp;locked.public: &nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;notify()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::lock_guard<decltype(mutex_)>&nbsp;lock(mutex_); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++count_; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;condition_.notify_one(); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;wait()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::unique_lock<decltype(mutex_)>&nbsp;lock(mutex_); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(!count_)&nbsp;//&nbsp;Handle&nbsp;spurious&nbsp;wake-ups. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;condition_.wait(lock); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--count_; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;bool&nbsp;try_wait()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::lock_guard<decltype(mutex_)>&nbsp;lock(mutex_); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(count_)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--count_; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;true; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;false; &nbsp;&nbsp;&nbsp;&nbsp;}};

精慕HU

我决定用我能写的最健壮的/通用的C+11信号量,尽可能地按照标准的风格来写(注意using semaphore = ...,你通常只会用这个名字semaphore类似于正常使用string不basic_string):template <typename Mutex, typename CondVar>class basic_semaphore {public:&nbsp; &nbsp; using native_handle_type = typename CondVar::native_handle_type;&nbsp; &nbsp; explicit basic_semaphore(size_t count = 0);&nbsp; &nbsp; basic_semaphore(const basic_semaphore&) = delete;&nbsp; &nbsp; basic_semaphore(basic_semaphore&&) = delete;&nbsp; &nbsp; basic_semaphore& operator=(const basic_semaphore&) = delete;&nbsp; &nbsp; basic_semaphore& operator=(basic_semaphore&&) = delete;&nbsp; &nbsp; void notify();&nbsp; &nbsp; void wait();&nbsp; &nbsp; bool try_wait();&nbsp; &nbsp; template<class Rep, class Period>&nbsp; &nbsp; bool wait_for(const std::chrono::duration<Rep, Period>& d);&nbsp; &nbsp; template<class Clock, class Duration>&nbsp; &nbsp; bool wait_until(const std::chrono::time_point<Clock, Duration>& t);&nbsp; &nbsp; native_handle_type native_handle();private:&nbsp; &nbsp; Mutex&nbsp; &nbsp;mMutex;&nbsp; &nbsp; CondVar mCv;&nbsp; &nbsp; size_t&nbsp; mCount;};using semaphore = basic_semaphore<std::mutex, std::condition_variable>;template <typename Mutex, typename CondVar>basic_semaphore<Mutex, CondVar>::basic_semaphore(size_t count)&nbsp; &nbsp; : mCount{count}{}template <typename Mutex, typename CondVar>void basic_semaphore<Mutex, CondVar>::notify() {&nbsp; &nbsp; std::lock_guard<Mutex> lock{mMutex};&nbsp; &nbsp; ++mCount;&nbsp; &nbsp; mCv.notify_one();}template <typename Mutex, typename CondVar>void basic_semaphore<Mutex, CondVar>::wait() {&nbsp; &nbsp; std::unique_lock<Mutex> lock{mMutex};&nbsp; &nbsp; mCv.wait(lock, [&]{ return mCount > 0; });&nbsp; &nbsp; --mCount;}template <typename Mutex, typename CondVar>bool basic_semaphore<Mutex, CondVar>::try_wait() {&nbsp; &nbsp; std::lock_guard<Mutex> lock{mMutex};&nbsp; &nbsp; if (mCount > 0) {&nbsp; &nbsp; &nbsp; &nbsp; --mCount;&nbsp; &nbsp; &nbsp; &nbsp; return true;&nbsp; &nbsp; }&nbsp; &nbsp; return false;}template <typename Mutex, typename CondVar>template<class Rep, class Period>bool basic_semaphore<Mutex, CondVar>::wait_for(const std::chrono::duration<Rep, Period>& d) {&nbsp; &nbsp; std::unique_lock<Mutex> lock{mMutex};&nbsp; &nbsp; auto finished = mCv.wait_for(lock, d, [&]{ return mCount > 0; });&nbsp; &nbsp; if (finished)&nbsp; &nbsp; &nbsp; &nbsp; --mCount;&nbsp; &nbsp; return finished;}template <typename Mutex, typename CondVar>template<class Clock, class Duration>bool basic_semaphore<Mutex, CondVar>::wait_until(const std::chrono::time_point<Clock, Duration>& t) {&nbsp; &nbsp; std::unique_lock<Mutex> lock{mMutex};&nbsp; &nbsp; auto finished = mCv.wait_until(lock, t, [&]{ return mCount > 0; });&nbsp; &nbsp; if (finished)&nbsp; &nbsp; &nbsp; &nbsp; --mCount;&nbsp; &nbsp; return finished;}template <typename Mutex, typename CondVar>typename basic_semaphore<Mutex, CondVar>::native_handle_type basic_semaphore<Mutex, CondVar>::native_handle() {&nbsp; &nbsp; return mCv.native_handle();}
打开App,查看更多内容
随时随地看视频慕课网APP