首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >等待atomic_bool

等待atomic_bool
EN

Stack Overflow用户
提问于 2013-02-17 19:47:06
回答 3查看 10.2K关注 0票数 9

我有两个线程和一个由第二个线程设置的标志。我可以使用atomic_bool,但我希望能够等待*在第一线程上设置标志。我该怎么做呢?

我想我不能使用condition_variable,因为如果第二个线程在第一个线程开始等待之前调用notify_one,线程将不会被唤醒。

此外,检查标志是否已经设置应该相当快。我想这应该是相当简单的,但我只是卡住了,所以我在这里问。提前谢谢。

*编辑:块当然,不忙-等待。抱歉,如果说得不清楚的话。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-02-17 20:29:31

在cbreak和Ravadre (评论)的帮助下,我从这里得到了:

代码语言:javascript
复制
int main()
{
    std::mutex m;
    std::condition_variable cv;

    std::thread t([&] {
            std::this_thread::sleep_for(std::chrono::seconds(1));
            std::unique_lock<std::mutex> lock(m);
            cv.wait(lock);
            std::cout << "Yay!\n";
    });

    cv.notify_one();
    t.join();
}

它通常根本不会终止,到这里:

代码语言:javascript
复制
int main()
{
    std::mutex m;
    std::condition_variable cv;
    bool flag = false;

    std::thread t([&] {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        std::unique_lock<std::mutex> lock(m);
        cv.wait(lock, [&] { return flag; });
        std::cout << "Yay!\n";
    });

    {
        std::lock_guard<std::mutex> lock(m);
        flag = true;
    }

    cv.notify_one();
    t.join();
}

它实际上完成了这项工作,但似乎仍然有很多不必要的开销。请随意发布一个同等但更好(或更优雅)的答案,我会很高兴地接受它。请只使用标准C++11,如果不是,请解释为什么标准C++11不能做到这一点。

编辑:我还编写了一个类safe_flag来封装它(再次感谢cbreak);请随时提出任何改进建议。

代码语言:javascript
复制
class safe_flag
{
    mutable std::mutex m_;
    mutable std::condition_variable cv_;
    bool flag_;

public:
    safe_flag()
        : flag_(false)
    {}

    bool is_set() const
    {
        std::lock_guard<std::mutex> lock(m_);
        return flag_;
    }

    void set()
    {
        {
            std::lock_guard<std::mutex> lock(m_);
            flag_ = true;
        }
        cv_.notify_all();
    }

    void reset()
    {
        {
            std::lock_guard<std::mutex> lock(m_);
            flag_ = false;
        }
        cv_.notify_all();
    }

    void wait() const
    {
        std::unique_lock<std::mutex> lock(m_);
        cv_.wait(lock, [this] { return flag_; });
    }

    template <typename Rep, typename Period>
    bool wait_for(const std::chrono::duration<Rep, Period>& rel_time) const
    {
        std::unique_lock<std::mutex> lock(m_);
        return cv_.wait_for(lock, rel_time, [this] { return flag_; });
    }

    template <typename Rep, typename Period>
    bool wait_until(const std::chrono::duration<Rep, Period>& rel_time) const
    {
        std::unique_lock<std::mutex> lock(m_);
        return cv_.wait_until(lock, rel_time, [this] { return flag_; });
    }
};
票数 12
EN

Stack Overflow用户

发布于 2013-02-17 21:13:06

代码语言:javascript
复制
bool go = false;
std::mutex mtx;
std::condition_variable cnd;

// waiting thread:
std::unique_lock<std::mutex> lck(mtx);
while (!go)
    cnd.wait(lock);
// when we get here we know that go is true, and we have the lock

// signalling thread:
{
std::unique_lock<std::mutex> lck(mtx);
go = true;
cnd.notify_one();
}
// now we've released the lock, so the waiting thread will make progress
票数 7
EN

Stack Overflow用户

发布于 2013-02-17 20:02:04

你的平台到底是什么?在我们使用的posix兼容平台上

代码语言:javascript
复制
  sem_t semaphore;
  sem_init( &semaphore , 0 , x );

来获得一个初始值为x的信号量。

代码语言:javascript
复制
 sem_wait(&semaphore ); sem_post(&semaphore);

您可以同步这两个线程。请记住将semaphore声明为全局变量,以确保两个线程都可以访问它(或通过任何其他实现相同功能的方法)。

长话短说,你可以:

代码语言:javascript
复制
sem_t semaphore;
sem_init(&semaphore, 0 , 0 );
void thread2(){
   sem_post(&semaphore);    //second thread --A
}
void thread1(){
    sem_wait(&semaphore);   // wait until thread2() executes line A
}

在Win32上也应该有类似的实用程序来实现相同的功能。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14920725

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档