一、线程对象如何获得?
线程对象的获取,可以分为以下几种情况:
- case1 无中生有,通过传递函数对象+参数的方法完成一个线程的构造
- case2 假借他人,通过默认构造函数并通过移动构造完成线程的创建
所以,我们标准库有以下的构造函数定义:
thread() noexcept;//since c++11
thread(thread&& other) noexcept;//since c++11
template
explicit thread(Function &&f,Args && ...args);//since c++11
thread(const thread&)=delete;//since c++11
- 第一个是默认构造,构造一个什么也不做的线程对象;
- 第二个是std::move()会调用的移动构造函数;
- 第三个是类模板,表示使用一个函数对象和若干个参数生成对应的线程类;
注意:线程不能拷贝,但是可以移动。移动之前应该保证移动对象是处于joinable状态,如果你默认构造一个线程,总是可以移动的,因为默认是joinable的
第三个构造函数是构造一个有实际还行意义的唯一方法,其模板参数如下:
- 一个函数对象
- 零个或者多个参数
参数很好理解,那么函数对象是什么,都有哪些种类呢?
二、函数对象函数对象std::function
是C++标准库定义的通用多态包装器,std::function 的实例能存储、复制及调用任何可复制构造 (CopyConstructible) 的可调用 (Callable) 目标:
- 普通函数
- lambda表达式
- bind表达式
- 其他可调用对象(如仿函数)
- 指向成员函数指针
- 成员数据是指向函数的指针
存储的可调用对象称为std::function
对象的目标,如果目标不存在,称函数对象为空,调用它将会抛出std::bad_function_call
错误。简单来说,函数对象类是存储函数对象的一个容器。
上面列举的可调用目标都可以用统一的容器std::function
封装。那么他都有哪些构造函数呢?
function() noexcept; //(1) (C++11 起)
function( std::nullptr_t ) noexcept;//(2) (C++11 起)
function( const function& other ); //(3) (C++11 起)
function( function&& other ); //(4) (C++11 起,C20止)
第二个构造函数是最常用的,构造的参数是一个std::nullptr_t
非空指针类型,也就是说:
- lambada
- 普通函数
- 指向函数成员的指针
- 数据成员是指针
都可以完成函数对象的构造!
注意:
- 线程函数参数要么是拷贝,要么是移动。如果是引用参数,请使用
std::ref
或者std::cref
包裹后传入。 - 线程的返回值将会被忽略。如果一个函数抛出一个异常,将会调用
std::terminate
,如果你确实需要返回一个值或者异常给调用这个线程的线程,那么你可以使用std::promise
或者std::async
。
#include
#include
using namespace std;
void show_even()
{
for(int i=0;i
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?