标准::线程 C++。更多线程相同的数据

Posted

技术标签:

【中文标题】标准::线程 C++。更多线程相同的数据【英文标题】:std::thread c++. More threads same data 【发布时间】:2013-02-26 01:51:41 【问题描述】:

我正在使用 Visual Studio 2012 和 C++11。我不明白为什么这不起作用:

void client_loop(bool &run)

    while ( run );


int main()

    bool running = true;
    std::thread t(&client_loop,std::ref(running));

    running = false ;
    t.join();

在这种情况下,线程t 的循环永远不会结束,但我明确地将running 设置为falserunrunning 具有相同的位置。我试图将running 设置为单个全局变量,但没有任何反应。我也尝试传递一个指针值,但什么也没有。

线程使用相同的堆。我真的不明白。谁能帮帮我?

【问题讨论】:

您的程序过早终止,无法观察到任何有趣的事情。 不,我忘了在这个例子中写“t.join()”.. :) 如果将running 设置为volatile 会怎样? @didierc:如果他将它设置为volatile,他可能会被欺骗以为他有工作代码。 Microsoft 定义了volatile,所以它可以工作,但标准不需要它。 @JerryCoffin thx,我想我之前的某个时候弄错了。我的立场是正确的。 【参考方案1】:

您的程序有未定义行为,因为它在running 变量上引入了数据竞争(一个线程写入它,另一个线程读取它)。

您应该使用互斥锁来同步访问,或者将running 设置为atomic<bool>

#include <iostream>
#include <thread>
#include <atomic>

void client_loop(std::atomic<bool> const& run)

    while (run.load());


int main()

    std::atomic<bool> running(true);
    std::thread t(&client_loop,std::ref(running));

    running = false ;
    t.join();

    std::cout << "Arrived";

查看工作中的live example。

【讨论】:

谢谢你,我(愚蠢地)认为如果第二个线程只读取数据就不需要预防措施了。我不知道“原子”变量:但现在我发现我很高兴。再次感谢 @MatteoGaleotti 它甚至可能在合理的架构上工作过(当然,尽管仍然是 UB),但这个无限循环不是那么简单,只需优化即可。 两个音符。首先,run 可能不应该被声明为const。诚然,编译器无法优化负载,但该函数仍然假定值发生了变化。其次,不需要.load()while (run) ; 也可以; run 在上下文中转换为bool,最终应用其operator bool() @PeteBecker:关于load(),你是对的,谢谢你指出这一点。关于const,我把它放在那里是为了指定client_loop() 本身不会修改该值。放置const 是否也意味着该函数不希望值改变?我会说答案是“不”,但你的评论似乎暗示它是“是”。如果是这样,你能扩大一点吗?【参考方案2】:

const 可能不会影响编译器对代码的查看。在单线程应用程序中,该值不会改变(并且这个特定程序毫无意义)。在多线程应用程序中,由于它是原子类型,编译器无法优化负载,所以实际上这里没有真正的问题。这实际上更多是风格问题。因为main 修改了该值,而client_loop 查找该修改,所以说该值为const 似乎不对。

【讨论】:

以上是关于标准::线程 C++。更多线程相同的数据的主要内容,如果未能解决你的问题,请参考以下文章

c++ 多线程与c多线程有啥区别?

支持多线程程序的 C++0X 标准

[编程基础] C++多线程入门8-从线程返回值

关于标准 C++ 多线程的简单问题 [重复]

并发编程基础概念

c++多线程编程:实现标准库accumulate函数的并行计算版本