C++11标准提供了thread类模板用于创建线程,该类模板定义在thread标准库中,因此在创建线程时,需要包含thread头文件。thread类模板定义了一个无参构造函数和一个变餐构造函数,因此在创建线程对象时,可以为线程传入函数,也可以不传入函数。需要注意的是,thread类模板不提供拷贝构造函数、赋值运算符重载等函数,因此线程对象之间不可以进行拷贝、赋值等操作。
除了构造函数,thread类模板还定义了两个常用的成员函数:join()函数和detach()函数。
(1)join()函数:该函数将线程和线程对象连接起来,既将子线程加入程序执行。join()函数是阻塞的,它可以阻塞主线程(当前线程),等待子线程工作结束之后,在启动主线继续执行任务。
(2)detach()函数:该函数分离线程与线程对象,既主线程和子线程可同时进行工作,主线程不必等待子线程结束。但是,detach()函数分离的线程对象不能再调用join()函数将它与线程连接起来。
程序举例:
#include <iostream>
#include <thread>
using namespace std;
void func(){
cout << "子线程工作" <<endl;
cout << "子线程工作结束"<<endl;
}
int main(){
cout <<"主线程工作"<<endl;
thread t(func); //创建线程对象t
t.join(); //将子线程加入程序执行
cout <<"主线程工作结束"<<endl;
return 0;
}
在MFC中的程序:
头文件:
#include <iostream>
#include <thread>
void receiveData();
void OpenThread(void);
void CloseThread(void);
头文件对应的点cpp文件:
#include <iostream>
#include <thread>
bool threadFlag = true;
void CUSBmywriteDlg:: receiveData() {
CString currentText = _T("Threadstart");
while (threadFlag) {
m_DataShowEdit.SetWindowText(currentText);
m_DataShowEdit.GetWindowText(currentText);
CString newText = _T("要追加的文本");
currentText += newText;
//m_DataShowEdit.SetWindowTextW(currentText);
}
}
void CUSBmywriteDlg::OpenThread() {
threadFlag = true;
std::thread t(&CUSBmywriteDlg :: receiveData,this);
t.detach();
}
void CUSBmywriteDlg::CloseThread() {
threadFlag = false;
}
void CUSBmywriteDlg::OnBnClickedRecvDataBtn()
{
// TODO: 在此添加控件通知处理程序代码
//按下此按钮后开始接受数据
//m_DataShowEdit.ModifyStyle(0, ES_AUTOHSCROLL | ES_MULTILINE);
DWORD Bytes;
BYTE RecvDataBuf[9];
//bool flag = false;
if (flag == false) {
hidDevice = OpenMyHidDevice();
if (INVALID_HANDLE_VALUE != hidDevice) {
m_RecvData.SetWindowText(_T("关闭设备"));
flag = true;
OpenThread();
}
}
else {
if (INVALID_HANDLE_VALUE != hidDevice) {
m_RecvData.SetWindowText(_T("打开设备"));
CloseHandle(hidDevice);
flag = false;
CloseThread();
}
}
说明:该程序不是完成的程序,只是我自己的记录。完整程序需要参考原项目。
有一个bug:
线程开始运行后,使用detach()继续主线程的运行,此时字线程中的函数停留在while循环中,会一直再次循环,无法结束子线程函数。当我点击按钮时,设置while中的条件为false,此时while检测条件已经不满足了,会继续执行while后面的语句,然后结束子线程中的函数吧。此时子线程应该就结束了吧(存有疑问)。