一,线程的创建与终止
线程是CPU最小的执行和调度单位。多个线程共享进程的资源。
创建线程比创建进程更快,开销更小。
创建线程的方法:pthread_create、std::thread。
pthread_create:传入的线程函数只有一个参数。
std::thread:传入的线程函数可以有任意数量的参数。
因为,thread类的构造函数是一个可变参数模板,可接收任意数目的参数,其中第一个参数是线程对应的函数名称。
std::thread调用以后返回一个线程类,每创建一个线程类,就会在系统中启动一个线程,并利用这个线程类来管理线程。
线程类可以被移动,但是不可以被复制,可以调用move()来改变线程的所有权。
线程的标识符是线程id,线程类可以调用this_thread::get_id()来获得当前线程的id。
创建线程以后,可以调用join()或者detach()来等待线程结束,join()会等启动的线程运行结束以后再继续执行当前代码,detach()会直接往后继续执行当前代码,而不需要等待启动的线程运行结束。如果调用detach()分离线程,该线程结束后,线程资源会自动被系统回收。
std::thread常用的创建线程类的方式有:
通过函数指针创建线程
通过函数对象创建线程
通过lambda表达式创建线程
通过成员函数创建线程
1.通过函数指针创建线程
代码样例:
函数
void counter(int id, int numIterations)
{
for(int i=0; i<numIterations; ++i){
cout << "Counter " << id << " has value " << i << endl;
}
}
利用函数创建线程:
thread t1(counter, 1, 6);
thread t2(counter, 2, 4);
t1.join();
t2.join();
注意,线程中的函数,比如counter(),在创建线程的时候,默认的传参方式是值拷贝,比如id,numIterations会被拷贝以后再传递到线程空间中。
2.通过函数对象创建线程
代码样例:
函数对象Counter:
class Counter
{
public:
Counter(int id, int numIterations)
:mId(id), mNumIterations(numIterations)
{
}
//重载运算符operator()
void operator()() const
{
for(int i=0; i < mNumIterations; ++i){
cout << "Counter " << mId << " has value " << i << endl;
}
}
private:
int mId;
int mNumIterations;
};
利用函数对象创建线程:
方法1:通过构造函数创建Counter类的一个实例,将实例传递给thread类
thread t1{Counter{1, 4}};
方法2:创建Counter类的一个实例c,将实例传递给thread类
Counter c(2, 5);
thread t2(c);
完整代码实现:
#include <thread>
#include <iostream>
using namespace std;
class Counter
{
public:
Counter(int id, int numIterations)
:mId(id), mNumIterations(numIterations)
{
}
//重载运算符operator()
void operator()() const
{
for(int i=0; i < mNumIterations; ++i){
cout << "Counter " << mId << " has value " << i << endl;
}
}
private:
int mId;
int mNumIterations;
};
int main(){
thread t1{Counter{1, 4}};
Counter c(2, 5);
thread t2(c);
t1.join();
t2.join();
cout << "Main thread end." << endl;
return 0;
}
运行结果:
Counter 1 has value 0
Counter 1 has value 1
Counter 1 has value 2
Counter 1 has value 3
Counter 2 has value 0
Counter 2 has value 1
Counter 2 has value 2
Counter 2 has value 3
Counter 2 has value 4
Main thread end.