使用 boost 线程:发出信号并等待终止
Posted
技术标签:
【中文标题】使用 boost 线程:发出信号并等待终止【英文标题】:Using a boost thread: Signal and wait for termination 【发布时间】:2014-08-01 14:32:07 【问题描述】:我目前正在编写一个 c/c++ dll 以供以后主要在 Delphi 中使用,而且我对 Delphi 中的线程比 c/c++ 更熟悉,尤其是 boost。所以我想知道如何实现以下场景?
class CMyClass
private:
boost::thread* doStuffThread;
protected:
void doStuffExecute(void)
while(!isTerminationSignal()) // loop until termination signal
// do stuff
setTerminated(); // thread is finished
;
public:
CMyClass(void)
// create thread
this->doStuffThread = new boost::thread(boost::bind(&CMyClass::doStuffExecute, this));
;
~CMyClass(void)
// finish the thread
signalThreadTermination();
waitForThreadFinish();
delete this->doStuffThread;
// do other cleanup
;
我有无数关于增强线程、信号和互斥锁的文章,但我不明白,可能是因为现在是星期五;)还是我认为这样做不可行?
问候 丹尼尔
【问题讨论】:
我会声明“volatile bool needStop”变量,并使用 thread::join 来等待您将 needStop 设置为 true 后实际停止的线程。 @VadimKalinsky,不不不! -volatile
不适用于多线程。使用std::atomic<bool>
。
【参考方案1】:
只需使用原子布尔值来告诉线程停止:
class CMyClass
private:
boost::thread doStuffThread;
boost::atomic<bool> stop;
protected:
void doStuffExecute()
while(!stop) // loop until termination signal
// do stuff
// thread is finished
;
public:
CMyClass() : stop(false)
// create thread
doStuffThread = boost::thread(&CMyClass::doStuffExecute, this);
;
~CMyClass()
// finish the thread
stop = true;
doStuffThread.join();
// do other cleanup
;
要等待线程完成,您只需加入它,这将阻塞,直到它完成并可以加入。无论如何你都需要加入线程才能销毁它,否则它会终止你的程序。
不需要使用指针和new
创建线程,直接使用boost::thread
对象即可。在堆上创建所有内容是浪费、不安全和糟糕的风格。
无需使用boost::bind
将参数传递给thread
构造函数。多年来boost::thread
一直支持将多个参数直接传递给其构造函数,并在内部进行绑定。
在创建新线程之前stop
已经初始化为false
很重要,否则如果新线程很快产生,它可能会在初始化之前检查stop
的值,并且可能会发生从未初始化的内存中读取一个true
的值,然后它就永远不会进入循环。
在风格方面,写foo(void)
被许多 C++ 程序员认为是令人厌恶的可憎之物。如果你想说你的函数不带参数,那就写foo()
。
【讨论】:
未定义的行为的哪一部分与您无关?如果没有原子,编译器可以将循环转换为:if (!stop) while (true) /* do work */
,因为它知道正在读取的非原子、非易失性变量不能更改,除非在具有未定义行为的程序中,因此它可以假设它永远不会更改跨度>
查看我之前的评论,或阅读Benign data races: what could possibly go wrong?。仅仅因为您不了解问题并不意味着它不是真实的。
How to miscompile programs with “benign” data races 中的第 2.3 节正是这种情况。这两个链接是由一些世界***的数据竞赛和多线程专家编写的,但是,嘿,也许他们只是偏执,你是对的。
volatile
对于 C++ 中的线程间通信既非必要也不充分。 drdobbs.com/parallel/volatile-vs-volatile/212701484
@BrandonKohn 多线程之于单线程,就像相对论之于经典力学一样。 您对同时性和事件顺序的直觉不会延续。此外,您引用的关于竞争条件的问答不是 C++ 特定的。对于 C++,标准有一个非常精确的声明,这是这里唯一相关的引用。以上是关于使用 boost 线程:发出信号并等待终止的主要内容,如果未能解决你的问题,请参考以下文章