为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C++ C
慕桂英3389331 2019-07-02 16:21:53
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也没有信号量,那么实现上述目标的最简单方法是什么呢?
查看完整描述

3 回答

?
慕村225694

TA贡献1880条经验 获得超4个赞

您可以通过互斥和条件变量轻松地构建一个:

#include <mutex>#include <condition_variable>class semaphore{private:
    std::mutex mutex_;
    std::condition_variable condition_;
    unsigned long count_ = 0; // Initialized as locked.public:
    void notify() {
        std::lock_guard<decltype(mutex_)> lock(mutex_);
        ++count_;
        condition_.notify_one();
    }

    void wait() {
        std::unique_lock<decltype(mutex_)> lock(mutex_);
        while(!count_) // Handle spurious wake-ups.
            condition_.wait(lock);
        --count_;
    }

    bool try_wait() {
        std::lock_guard<decltype(mutex_)> lock(mutex_);
        if(count_) {
            --count_;
            return true;
        }
        return false;
    }};


查看完整回答
反对 回复 2019-07-02
?
精慕HU

TA贡献1845条经验 获得超8个赞

我决定用我能写的最健壮的/通用的C+11信号量,尽可能地按照标准的风格来写(注意using semaphore = ...,你通常只会用这个名字semaphore类似于正常使用string不basic_string):


template <typename Mutex, typename CondVar>

class basic_semaphore {

public:

    using native_handle_type = typename CondVar::native_handle_type;


    explicit basic_semaphore(size_t count = 0);

    basic_semaphore(const basic_semaphore&) = delete;

    basic_semaphore(basic_semaphore&&) = delete;

    basic_semaphore& operator=(const basic_semaphore&) = delete;

    basic_semaphore& operator=(basic_semaphore&&) = delete;


    void notify();

    void wait();

    bool try_wait();

    template<class Rep, class Period>

    bool wait_for(const std::chrono::duration<Rep, Period>& d);

    template<class Clock, class Duration>

    bool wait_until(const std::chrono::time_point<Clock, Duration>& t);


    native_handle_type native_handle();


private:

    Mutex   mMutex;

    CondVar mCv;

    size_t  mCount;

};


using semaphore = basic_semaphore<std::mutex, std::condition_variable>;


template <typename Mutex, typename CondVar>

basic_semaphore<Mutex, CondVar>::basic_semaphore(size_t count)

    : mCount{count}

{}


template <typename Mutex, typename CondVar>

void basic_semaphore<Mutex, CondVar>::notify() {

    std::lock_guard<Mutex> lock{mMutex};

    ++mCount;

    mCv.notify_one();

}


template <typename Mutex, typename CondVar>

void basic_semaphore<Mutex, CondVar>::wait() {

    std::unique_lock<Mutex> lock{mMutex};

    mCv.wait(lock, [&]{ return mCount > 0; });

    --mCount;

}


template <typename Mutex, typename CondVar>

bool basic_semaphore<Mutex, CondVar>::try_wait() {

    std::lock_guard<Mutex> lock{mMutex};


    if (mCount > 0) {

        --mCount;

        return true;

    }


    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) {

    std::unique_lock<Mutex> lock{mMutex};

    auto finished = mCv.wait_for(lock, d, [&]{ return mCount > 0; });


    if (finished)

        --mCount;


    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) {

    std::unique_lock<Mutex> lock{mMutex};

    auto finished = mCv.wait_until(lock, t, [&]{ return mCount > 0; });


    if (finished)

        --mCount;


    return finished;

}


template <typename Mutex, typename CondVar>

typename basic_semaphore<Mutex, CondVar>::native_handle_type basic_semaphore<Mutex, CondVar>::native_handle() {

    return mCv.native_handle();

}


查看完整回答
反对 回复 2019-07-02
  • 3 回答
  • 0 关注
  • 575 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信