前言:
通常一个程序运行起来,也就等于一个进程在运行,这个进程中会有一个主线程自动创建并运行,当程序的main()函数返回之后那么此主线程也就运行结束,也意味着进程运行结束。
主线程是从main()函数开始运行,main()函数就可以看做主线程的入口函数。
1. C++如何创建一个线程。
创建一个最简单的线程只需要注意三点:
- 第一:需要包含thread头文件;
- 第二:需要提供一个线程入口函数;
- 第三:我们直接在main函数中创建thread。
#include <thread>
#include <iostream>
using namespace std;
void myThreadTest()
{
cout << "the thread running..."<<endl;
count<< "线程运行完毕"<<endl;
return;
}
int main()
{
//创建了线程,此处的线程入口函数则是myThreadTest,并且开始执行线程
thread myThread(myThreadTest);
/***
此处可以调用join()函数和detach()函数
join()函数可以理解为让主线程的等待该子线程完成,然后主线程再继续执行。
detach()的作用:是将子线程和主线程的关联分离,也就是说detach()后
子线程在后台独立继续运行,主线程无法再取得子线程的控制权,
即使主线程结束,子线程未执行也不会结束。
当主线程结束时,由运行时库负责清理与子线程相关的资源。
*/
myThread.join();
/***
joinable()主要是用于判断是否可以成功使用join()或者detach()
如果返回true,证明可以调用join()或者detach()
如果返回false,证明调用过join()或者detach(),就不能再调用了join()和detach()
*/
if(myThread.joinable())
{
cout<<"这里可以调用函数join()或detach()"<<endl;
}
else
{
cout<<"反之,不能调用函数join()和detach()"<<endl;
}
return 0;
}
可以看到,线程类参数其实是一个可调用对象。c++中可调用对象可以是函数、函数指针、lambda表达式、bind创建的对象或者重载了函数调用运算符的类对象。
2.其他创建线程的方法:
那么也就意味着还有其他创建线程的方法:
#include <QCoreApplication>
#include <thread>
#include <iostream>
using namespace std;
//方法一:重载了函数调用运算符的类对象,此类中编写了圆括号重载函数,
//然后可以创建该类的对象,并将此对象作为线程入口地址
class myThreadTest
{
public:
void operator()()
{
cout<<"测试使用圆括号重载函数方法..."<<endl;
cout<<"次函数运行结束"<<endl;
}
};
//方法三:把某个类中的某个函数作为线程的入口地址
class myThreadTest2
{
public:
void pushNumber()
{
cout<<"push one number"<<endl;
}
void popNumber()
{
cout<<"pop one number"<<endl;
}
};
void myThreadTest()
{
cout << "the thread running..."<<endl;
count<< "线程运行完毕"<<endl;
return;
}
int main()
{
//创建了线程,此处的线程入口函数则是myThreadTest,并且开始执行线程
thread myThread(myThreadTest);
/***
此处可以调用join()函数和detach()函数
join()函数可以理解为让主线程的等待该子线程完成,然后主线程再继续执行。
detach()的作用:是将子线程和主线程的关联分离,也就是说detach()后
子线程在后台独立继续运行,主线程无法再取得子线程的控制权,
即使主线程结束,子线程未执行也不会结束。
当主线程结束时,由运行时库负责清理与子线程相关的资源。
*/
myThread.join();
/***
joinable()主要是用于判断是否可以成功使用join()或者detach()
如果返回true,证明可以调用join()或者detach()
如果返回false,证明调用过join()或者detach(),就不能再调用了join()和detach()
*/
if(myThread.joinable())
{
cout<<"这里可以调用函数join()或detach()"<<endl;
}
else
{
cout<<"反之,不能调用函数join()和detach()"<<endl;
}
myThreadTest myThreadObj;
thread myThread2(myThreadObj);
myThread2.detach();
//方法二: 创建lambda表达式
auto lambdaThreadTest = []{
cout <<"创建lambda表示进行测试"<<endl;
};
thread myThread3(lambdaThreadTest);
myThread3.join();
/***
方法三:
第一个&意思是取址,第二个&意思是引用,相当于std::ref(s)
thread oneobj(&Data_::SaveMsh,s)传值也是可以的
在其他的构造函数中&obj是不会代表引用的,会被当成取地址
*/
myThreadTest2 myThreadT2;
thread myThread4(&myThreadTest2::pushNumber,&myThread2);
thread myThread5(&myThreadTest2::popNumber,&myThread2);
myThread4.join();
myThread5.join();
return 0;
}