我正在使用调用beginthreadex,endthreadex在Visual Studio C++中进行一些多线程编程.
我创建了一个子线程thread1.子线程运行在一个永不退出的函数上,因为它具有无限循环.现在,如果父线程因错误终止或成功完成,子线程是否也会退出?我的疑问是 - 即使在主程序退出后,是否存在子线程仍处于活动状态的情况?
对于linux,这种情况应该怎样?
我不明白为什么这个简单的代码片段有死锁:
#include <atomic>
#include <thread>
#include <memory>
using namespace std;
class Test {
public:
Test() : mExit( false )
{
mThread = thread( bind( &Test::func, this ) );
}
~Test()
{
if ( mThread.joinable() )
{
mExit = true;
mThread.join();
}
}
private:
void func()
{
while ( !mExit )
{
// do something
}
}
private:
atomic< bool > mExit;
thread mThread;
};
typedef unique_ptr< Test > TestPtr;
TestPtr gTest;
int main()
{
gTest = TestPtr( new Test ); …Run Code Online (Sandbox Code Playgroud) 根据C++ 14标准,非静态成员变量按照它们在类中声明的顺序进行初始化.下面的减少代码依赖于此规则来控制线程函数.
class foo
{
foo():
keep_going{true},
my_thread(&foo::go,this)
{}
void go()
{
while(keep_going)
check a std::condition_variable and do some work;
}
bool keep_going;
std::thread my_thread;
}
Run Code Online (Sandbox Code Playgroud)
注意,它keep_going是在线程对象之前声明的,应该true在线程进入go函数时设置为.这很好,似乎工作正常.
但是,这是多线程代码,并且偏执是值得的,所以我有两个问题:
1依赖这样的初始化顺序是否安全?没有处理线程,我的真实对象没有意义,所以我想在构造函数中设置它.
2当代码依赖于初始化顺序等相对模糊的东西时,给别人提供代码是不安全的吗?
考虑以下代码。以下所有内容均使用 v140 C++ 运行时在 Visual Studio 2015 中编译和执行:
#include <thread>
#include <atomic>
#include <sstream>
#include <Windows.h>
struct StaticThreadTest
{
~StaticThreadTest()
{
_terminationRequested = true;
if (_thread.joinable())
_thread.join();
std::ostringstream ss;
ss << "Thread finished gracefully: " << _threadFinishedGracefully << "\n";
OutputDebugStringA(ss.str().c_str());
}
void startThread()
{
_thread = std::thread([&]() {
while (!_terminationRequested);
_threadFinishedGracefully = true;
});
}
std::thread _thread;
std::atomic<bool> _terminationRequested {false};
std::atomic<bool> _threadFinishedGracefully {false};
};
static StaticThreadTest thread;
int main()
{
thread.startThread();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它按预期工作 - 打印“线程正常完成:1”并且应用程序退出。
但是,如果我将此代码移至 DLL(创建一个空 DLL,从中导出一个函数,将该对象放置 …