C++11 thread

std::thread是C++11中提供多线程编程模块。使用时需要包含头文件。

简单说一下thread的用法

1 构造函数

构造函数是构造thread对象的,thread只是一个管理线程的类,并不是所有的thread对象都绑定一个实际的可执行的线程。也就是说有的thread对象并没有创建一个可执行的线程。

构造函数 函数
default(1) thread() noexcept
initialization (2) template
explicit thread (Fn&& fn, Args&&… args);
copy [deleted] (3) thread (const thread&) = delete;
move (4) thread (thread&& x) noexcept;

1、默认构造函数

// 示例代码
std::thread t;

默认构造函数是单纯地构造一个thread对象,并没有绑定一个可执行线程,也就是说并没有创建一个线程。

2、初始化构造函数

构造一个表示新的可执行线程的thread对象。新的可执行线程调用fn函数,args作为函数的参数。

构造对象的完成是与fn函数的副本的调用时同步的。

其实就是重载构造函数,有传递线程函数和函数参数,这种构造函数直接创建一个线程,并默认开始执行函数。

// 示例代码
#include 
#include 

using namespace std

void func()
{
	cout << "Thread is running !" << endl;
}
int main()
{
	thread t(func);

	getchar();
}

运行结果如下:
在这里插入图片描述

当然上面代码还有一点小问题,正常执行后当程序退出时会出现如下错误:

C++11 thread_第1张图片
这是因为并没有设定新创建的线程与当前线程在销毁时的方式,这个在后面会详细叙述。

3、拷贝构造函数

拷贝构造函数是被禁用的,也就是说thread对象是不支持复制的

4、移动构造函数
构造一个thread对象,该对象获取x(是另一个thread对象)所管理的可执行线程。这个操作并不影响线程的执行。它只是简单了更改了线程的所有者。从而x不再具有管理原来线程的能力,即不代表原来的线

可joinable的thread对象在被销毁之前,需要被joined或者detached。 这也是为什么在2中会出现相应的错误。
这里解释一下joinable,join,detach

joinable
joinable是thread对象的一个属性。如果一个thread对象代表一个可执行线程则该线程是joinable的,一个thread对象在一下三种情况下是非joinable的:
a、如果该对象是用默认构造函数构造的
b、如果该对象的线程被移动到其他对象了,也就是被当作参数传递给move构造函数。
c、如果该对象已经调用过join或者detach。

joined和detched
join和detach是协调主线程和被创建的子线程之间的同步关系的两种方式。
join()直到thread对象所管理的线程执行结束后才会返回。
detach()函数立刻返回。

所以当调用join()则表示主线程和子线程属于同步状态,当调用detach()则表示主线程和子线程属于异步状态。示例如下:

#include 
#include 
#include 
#include 

using namespace std;

void func1()
{
	this_thread::sleep_for(chrono::milliseconds(2000));
	cout << "Thread1 is running !" << endl;
}

void func2()
{
	this_thread::sleep_for(chrono::milliseconds(3000));
	cout << "Thread2 is running !" << endl;
}

int main()
{
	thread t1(func1);
	thread t2(func2);
	t1.join();
	t2.detach();
	cout << "Main thread is running !" << endl;
	getchar();
}

结果如下:

C++11 thread_第2张图片
从结果很容易可以看出join()和detach()的区别。t1.join()时主线程阻塞。知道t1线程运行完毕,到t2.detach(),主线程和t2运行互不干涉。

2 其他成员函数

get_id()

获取线程的id

joinable()

判断是否可joinable

join()

该函数当线程执行完毕则返回。该函数同步了函数返回和线程中所有操作完成的时刻。该函数会阻塞调用该函数的线程。

当调用该函数后,thread对象则为non-joinable,同时该线程可以安全地被销毁。

detach()

使调用该函数的线程和thread对象所代表的线程分离,使他们可以独立的执行。

两个线程都不会被阻塞,也没有任何同步。不过这里要注意如果thread对象是在当前线程中创建的,那么需要注意当前线程只想完毕后会销毁thread对象。所以有可能出现thread仍在执行,但是thread对象被销毁的情况。

该函数被调用后,thread对象变为non-joinable,并且可以被安全销毁。

你可能感兴趣的:(C/C++)