C++11线程指南(五)--线程的移动语义实现

1. 线程的移动语义实现

基于前面几章介绍的移动语义,我们用它来实现线程。

#include <iostream>
#include <thread>
#include <vector>
#include <algorithm>
#include <cassert>

int main()
{
	std::vector<std::thread> workers;
	for (int i = 0; i < 5; i++) {
		auto t = std::thread([i]()
		{
			std::cout << "thread function: " << i << "\n";
		});
		workers.push_back(std::move(t));
	}
	std::cout << "main thread\n";

	std::for_each(workers.begin(), workers.end(), [](std::thread &t)
	{
		assert(t.joinable());
		t.join();
	});

	return 0;
}

运行结果为:

thread function: thread function: thread function: 01

thread function: 3

2

main thread

thread function: 4

接下来对代码进行一些改变。将线程函数task()独立出来。

#include <iostream>
#include <thread>
#include <vector>
#include <algorithm>
#include <cassert>

void task(int i)
{
	std::cout<<"worker : "<<i<<std::endl;
}

int main()
{
	std::vector<std::thread> workers;
	for (int i = 0; i < 5; i++) {
		auto t = std::thread(&task, i);
		workers.push_back(std::move(t));
	}
	std::cout << "main thread" << std::endl;

	std::for_each(workers.begin(), workers.end(), [](std::thread &t)
	{
		assert(t.joinable());
		t.join();
	});

	return 0;
}

运行结果为:

worker : worker : 02

worker : 3

worker : 1

main thread

worker : 4

2. 通过引用传递线程参数

下面将线程函数的参数改为引用

void task(int &i)
{
	std::cout << "worker : " << i << "\n";
}

与此同时,线程的构造函数同样需要相应的修改

auto t = std::thread(&task, std::ref(i));

但是,上面程序看似可以工作,不过不是一个好的设计,因为多个线程在同时使用一个指向相同对象的引用。

C++11线程指南(五)--线程的移动语义实现

时间: 2024-08-25 18:36:20

C++11线程指南(五)--线程的移动语义实现的相关文章

【转】C++11 并发指南五(std::condition_variable 详解)

http://www.cnblogs.com/haippy/p/3252041.html 前面三讲<C++11 并发指南二(std::thread 详解)>,<C++11 并发指南三(std::mutex 详解)>分别介绍了 std::thread,std::mutex,std::future 等相关内容,相信读者对 C++11 中的多线程编程有了一个最基本的认识,本文将介绍 C++11 标准中 <condition_variable> 头文件里面的类和相关函数. &l

C++11 并发指南系列(转)

本系列文章主要介绍 C++11 并发编程,计划分为 9 章介绍 C++11 的并发和多线程编程,分别如下: C++11 并发指南一(C++11 多线程初探)(本章计划 1-2 篇,已完成 1 篇) C++11 并发指南二(std::thread 详解)(本章计划 1-2 篇,已完成 1 篇) C++11 并发指南三(std::mutex 详解)(本章计划 1-2 篇,已完成 2 篇) C++11 并发指南三(std::mutex 详解) C++11 并发指南三(Lock 详解) C++11 并发

C++11线程指南(二)--Lambda线程实现

1. Thread with lambda function 基于前一章中的Lambda程序,我们进行了扩展,当前创建5个线程. #include<iostream> #include<thread> #include<vector> #include<algorithm> int main() { std::vector<std::thread> threadVec; for(int i=0; i<5; ++i){ threadVec.p

C++11线程指南(四)--右值引用与移动语义

1. 按值传递 什么是按值传递? 当一个函数通过值的方式获取它的参数时,就会包含一个拷贝的动作.编译器知道如何去进行拷贝.如果参数是自定义类型,则我们还需要提供拷贝构造函数,或者赋值运算符来进行深拷贝.然而,拷贝是需要代价的.在我们使用STL容器时,就存在大量的拷贝代价.当按值传递参数时,会产生临时对象,浪费宝贵的CPU以及内存资源. 需要找到一个减少不必要拷贝的方法.移动语义就是其中一种. 2. 右值引用 此处介绍右值引用的目的,是为了实现后面的移动语义. 右值引用使得我们可以分辨一个值是左值

C++11线程指南(七)--死锁

1. 死锁 在多个mutex存在的时候,可能就会产生死锁. 避免死锁的一个最通用的方法是,总是按照相同的顺序来lock the two mutexes, 即总是先于mutex B之前lock mutex A,这样就不会有死锁的可能.有时,这种方法很简单实用,当这些mutexes用于不同的目标.但是,当mutexes用于包含相同类的一个实例时,就不是那么容易了. 例如,如下面程序所示,相同类的两个实例之间交互数据.为了保证数据交互不换并发影响,两个实例都使用mutex进行保护.但是当mutex被嵌

C++11线程指南(七)--资源竞争条件

1. 接口设计1 下面例子使用vector实现了一个栈.两个线程轮流从中弹出元素. #include <iostream> #include <thread> #include <mutex> #include <string> #include <vector> std::mutex myMutex; class Stack { public: Stack() {}; ~Stack() {}; void pop(); int top() { r

Python线程指南(转)

1. 线程基础 1.1. 线程状态 线程有5种状态,状态转换的过程如下图所示: 1.2. 线程同步(锁) 多线程的优势在于可以同时运行多个任务(至少感觉起来是这样).但是当线程需要共享数据时,可能存在数据不同步的问题.考虑这样一种情况:一个列表里所有元素都是0,线程"set"从后向前把所有元素改成1,而线程"print"负责从前往后读取列表并打印.那么,可能线程"set"开始改的时候,线程"print"便来打印列表了,输出就成

C# 线程(五):线程池

From : http://kb.cnblogs.com/page/42531/ 在多线程的程序中,经常会出现两种情况: 一种情况: 应用程序中,线程把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响应 这一般使用ThreadPool(线程池)来解决: 另一种情况:线程平时都处于休眠状态,只是周期性地被唤醒 这一般使用Timer(定时器)来解决: ThreadPool类提供一个由系统维护的线程池(可以看作一个线程的容器),该容器需要 Windows 2000 以上系统支持,因为其中某

Python全栈开发之11、进程和线程

一.线程 多任务可以由多进程完成,也可以由一个进程内的多线程完成,一个进程内的所有线程,共享同一块内存python中创建线程比较简单,导入threading模块,下面来看一下代码中如何创建多线程. def f1(i): time.sleep(1) print(i) if __name__ == '__main__': for i in range(5): t = threading.Thread(target=f1, args=(i,)) t.start() print('start') # 主