标准::线程 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
设置为false
。 run
和 running
具有相同的位置。我试图将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++。更多线程相同的数据的主要内容,如果未能解决你的问题,请参考以下文章