进程与线程:
一个程序创建运行就是一个进程,一个进程有一个主线程,主线程唯一
主线程执行main函数中的代码,当main函数执行完毕,主线程终止,其生命周期与进程一致。
在主线程以外可以通过代码创建其他线程来执行函数或者其他程序。
c++头文件 :
#include <thread>
创建线程一:
线程执行函数
例如要创建线程执行函数 hello()
void hello()
{
cout<<"hello"<<endl;
}
只需要在函数里面调用创建线程调用:
void main()
{
......
thread t1(hello);
......
t1.join();
return 0;
}
join()
这里提到了一个join()函数,他表示阻塞主程序,当主线程等待子线程执行完后,主线程才开始往下走。
detach()
当主线程需要等待多子线程执行结束,这在有些情况下不太好,于是出现了detach()这个函数,这个函数使主线程不需要等待子线程执行完成,当主线程执行完毕,子线程还没执行完时,这时子线程会被系统后台接管运行,当这些个线程执行完毕后,由运行库负责清理该进程相关的资源。
thread mythread(hello);
mythread.detach();
detach()使线程失去我们自己的控制,由后台接管。
通常情况下主线程等子线程。一旦detach()之后不能再用join(),最常用的是要控制线程的生命周期。
joinable()
判断是否可以成功使用join()或者detach()
创建线程二:
通过类构造一个可调用对象
//不带参数
class Mythread{
public:
void operator()()
{
cout<<"strat a thread success!"<<endl;
}
};
//类对象
Mythread mytd;
thread mythread(mytd);
mythread.join();
thread 参数传递
参数注意生命周期问题:
#include <iostream>
#include <thread>
using namespace std;
void func_str(const string & str)
{
cout << "data is " << str << '\n';
}
void start_thread(void)
{
char buffer[6] = {'a','b','c','d','e','\0'};
thread t(func_str, string(buffer));
t.join();
}
int main(int argc, char** argv)
{
thread t1(start_thread);
t1.join();
return 0;
}
创建线程三:
Lambda函数
lambda函数(匿名函数)是一个纯函数体,没有名字。它可以在适当的位置调用。lambda函数可以捕获它的调用上下文。这就是为什么他们经常被称为闭包。
#include <iostream>
#include <thread>
int main()
{
std::thread t([]()
{
std::cout << "thread function\n";
});
std::cout << "main thread\n";
t.join();
return 0;
}