std::thread 是C++11的新特性,对于windows来说,取代了原来的静态方法的创建方式
DWORD WINAPI ThreadUtil::ThreadProc(LPVOID lpParameter)
主要函数
joinable():用于检测线程是否有效。
joinable : 代表该线程是可执行线程。
not-joinable :通常一下几种情况会导致线程成为not-joinable
1) 由thread的缺省构造函数构造而成(thread()没有参数)。
2) 该thread被move过(包括move构造和move赋值)
3) 该线程调用过join或者detach
thread::join(): 阻塞当前线程,直至 *this 所标识的线程完成其执行。*this 所标识的线程的完成同步于从 join() 的成功返回。
该方法简单暴力,主线程等待子进程期间什么都不能做。thread::join()会清理子线程相关的内存空间
注意事项
在析构之前一定要显式调用,否则程序会出现crash
if(thread.joinable())
thread.join()
测试代码
- ThreadUtil.h文件
class ThreadUtil
{
public:
static DWORD WINAPI ThreadProc(LPVOID lpParameter);
int threadTest();
void testJoin();
//~ThreadUtil();
public:
std::thread testThread;
};
2.ThreadUtil.cpp文件
其中threadTest 与 ThreadProc 是传统的创建与调用thread的方式
#include "pch.h"
#include "ThreadUtil.h"
#include <iostream>
#include <winbase.h>
#include <tchar.h>
using namespace std;
DWORD WINAPI ThreadUtil::ThreadProc(LPVOID lpParameter)
{
for (int i = 0; i < 5; ++i)
{
std::cout << "子线程:i = " << i << std::endl;
Sleep(100);
}
return 0L;
}
int ThreadUtil::threadTest()
{
//创建一个线程
HANDLE thread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
//关闭线程
CloseHandle(thread);
//主线程的执行路径
for (int i = 0; i < 5; ++i)
{
std::cout << "主线程:i = " << i << std::endl;
Sleep(100);
}
return 0;
}
void ThreadUtil::testJoin()
{
if (testThread.joinable())
{
std::cout << "is joinable" << std::endl;
testThread.join();
}
testThread = std::thread([]() {
std::cout << "is ini" << std::endl;
});
}
//ThreadUtil::~ThreadUtil()
//{
// if (testThread.joinable())
// {
// testThread.join();
// }
//}
main函数
int main()
{
ThreadUtil threadUtil;
threadUtil.testJoin();
std::cout << "Hello World!\n";
}
先把析构中的代码去除,调用testJoin,直接crash在thread的析构函数中,会主动的调用terminate函数
注释掉析构函数中的代码,一切ok
原因
C++标准中希望程序员必须主动的去调用join
所以在thread的析构函数中,会判断线程是否为joinable,如果joinable,就会调用terminate,这就是上面程序出现crash的原因
那么为什么C++标准中不去显式的调用join函数或者detached函数,让程序处于不可联结的状态
1.若调用join,线程会一直等待子线程的退出,耗时很长
2.若调用detached,切断了子线程与主线程之间的链接,其中的lambda表达式可能使用了全局或者局部的变量,指针可能出现悬空的状态
解决方案
封装std::thread代码,具体例子再研究一下
参考链接
C++11: What happens if you don’t call join() for std::thread
std::thread对象的析构