理解多线程(二)

前言

上篇已经讲到,线程间的同步,和线程访问公用数据安全是存在问题的。这篇主要理解C++11标准上处理这些问题的方法。

std::thread

c++通过std:thread操作线程,因此使用 std::thread 时需要包含 #include 头文件。

构造函数

thread();//默认构造函数,没有执行的实例对象
thread (fun,_1,_2,...)//初始化构造函数,有执行的实例对象,可以传递普通函数,类方法,lambda表达式
thread(const thread&);//复制构造函数,已经删除该构造方法
thread(thread && x);//move构造函数 ,只能给已经分配了执行实例对象的线程构造,且构造后原来的线程对象就不能使用。

栈上:

 std::thread t1(fun);
 std::thread th[3]{thread(fun), thread(fun), thread(fun)}; 

堆上:

	std::thread * t1(new std::thread(fun));
	std::thread *pth(new std::thread[3]{ std::thread(fun), std::thread(fun), std::thread(fun) });

赋值

只支持move赋值,也是只能是分配了实例对象的线程赋值,且赋值后,原来的线程对象不能使用

	std::thread t1();
	std::thread t2(fun);
	std::thread t3 = std::move(t2);
	std::thread t3 = std::move(t1);//error

成员函数

join:
主线程阻塞等待子线程完成后释放子线程资源,再继续进行,如果不加join,主线程不等待,会报错。

	std::thread t2(mythread);
	t2.join();

joinable:
检查线程是否可被 join,是否是活跃的线程对象

if (t1.joinable())    t1.join();

get_id:
获取线程 ID,返回一个类型为 std::thread::id 的对象

std::thread::id t1_id = t1.get_id();

detach:
将当前线程对象所代表的执行实例与该线程对象分离,使得线程的执行可以单独进行,。一旦线程执行完毕,它所分配的资源将会被释放。
swap:
交换两个线程对象所代表的底层句柄,即id.

std::swap(t1, t2);
t1.swap(t2);

hardware_concurrency:
获得电脑cpu核心数量

	auto a=std::thread::hardware_concurrency();

std::this_thread 命名空间

get_id: 获取线程 ID。
yield: 暂停当前的线程执行。

do {
		std::this_thread::yield();
	} while (//do something);

sleep_until: 线程sleep到某个时间点重新唤醒。sleep1秒

	auto a = std::chrono::high_resolution_clock::now() + std::chrono::microseconds(1000);
	std::this_thread::sleep_until(a);

sleep_for: 线程休眠某个指定的时间段,该线程才被重新唤醒。sleep1秒

std::this_thread::sleep_for(std::chrono::microseconds(1000));

最后

了解了基本的线程使用,线程的同步可以使用join实现,甚至std::this_thread的sleep也能粗略的同步。后面是线程的互斥量,信号量来实现线程数据的安全访问。

猜你喜欢

转载自blog.csdn.net/qq_35651984/article/details/84928904