C++多线程 thread.h c++11

本文详细介绍了C++11中`thread.h`头文件的使用,包括`thread`类和`this_thread`命名空间。`thread`类用于表示执行线程,具备`id`和`native_handle_type`成员类型,以及构造函数、`join`、`detach`等成员函数。`this_thread`命名空间提供如`get_id`、`yield`、`sleep_until`和`sleep_for`等功能,帮助开发者管理当前线程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

 

thread.h

class thread

成员类型:id 和 native_handle_type

成员函数

namespace std::this_thread


thread.h

声明thread类和this_thread命名空间的头文件

 

class thread

表示各个执行线程。

执行线程是一个指令序列,它可以在多线程环境中与其他这样的序列同时执行,同时共享相同的地址空间。

一个初始化的线程对象表示一个正在执行的活动线程;这样的线程对象是可接合的,并且具有唯一的线程id。

默认构造的(未初始化的)线程对象是不可接合的,它的线程id是所有不可接合线程的通用id。

如果从可接合线程移动,或者在它们上调用join或detach,可接合线程将变得不可接合。

 

成员类型:id native_handle_type

id

这种类型的值由thread::get_id和this_thread::get_id返回,用来标识线程。

默认构造的thread::id对象的值标识不可连接的线程,因此与任何此类线程的成员thread::get_id返回的值比较。

对于可接合线程,thread::get_id返回该类型的唯一值,与其他可接合或不可接合线程的返回值不相等。

注意,某些库实现可能会重新利用终止线程的thread::id值,该线程不能再被连接。

 

noexcept id ();/ /默认构造函数

构造thread::id值,表示所有不可连接的线程。

id对象是可以复制的

 

typedef /* implementation-defined */ native_handle_type;

本地句柄类型,只有库实现支持该成员类型时,该成员类型才会出现在类thread中。

它是thread::native_handle返回的类型,带有关于线程的具体实现信息。

 

成员函数

构造函数

default (1)

thread() noexcept;

initialization (2)

template <class Fn, class... Args>
explicit thread (Fn&& fn, Args&&... args);

copy [deleted] (3)

thread (const thread&) = delete;

move (4)

thread (thread&& x) noexcept;

 

构造一个线程对象:

(1)默认构造函数

构造不表示任何执行线程的线程对象。

(2)初始化的构造函数

构造一个线程对象,表示一个新的可接合的执行线程。新的执行线程调用fn,将args作为参数传递(使用其左值或右值引用的衰减副本)。该构造的完成与fn副本的调用开始同步。

(3)拷贝构造函数

删除构造函数形式(线程对象不能被复制)。

(4)移动构造函数

构造一个thread对象,获取由x表示的执行线程(如果有的话)。这个操作不会以任何方式影响移动线程的执行,它只是传输它的处理程序。x对象不再代表任何执行线程。可接合的线程对象应该在销毁之前被接合或分离。

 

fn - 指向函数的指针,指向成员的指针,或任何一种可移动构造的函数对象(即,其类定义了operator()的对象,包括闭包和函数对象)。返回值(如果有的话)会被忽略。

 

args…… - 传递给fn调用的参数(如果有的话)。它们的类型应是可移动构造的。如果fn是一个成员指针,第一个参数应该是一个定义了该成员的对象(或者引用,或者指向该成员的指针)。

 

x - 将其状态移动到已构造对象的线程对象。

 

Fn和Args……是模板形参:如果是隐式推断的,则它们是参数绑定的合适左值或右值引用类型。但是请注意,在新线程中调用fn时,fn和args的衰减副本…总是使用(请参阅std::ref以获得使引用可复制的包装器类)。

 

初始化构造函数(2)在以下条件下抛出异常:

如果它生成的任何副本(Fn和Args…的衰减类型)的构造抛出,它也抛出。

根据库的实现,这个构造函数还可以抛出异常来报告其他情况(例如bad_alloc或带有其他错误条件的system_error)。

注意,如果函数调用(即fn本身)抛出异常,则由新线程处理。如果此调用以未捕获的异常终止,则调用terminate()。

 

析构函数

~thread();

销毁线程对象。如果撤销时线程是可接合的,则调用terminate()。

 

操作符重载:std::thread::operator=

move (1)

thread& operator= (thread&& rhs) noexcept;

copy [deleted] (2)

thread& operator= (const thread&) = delete;

Move-assign线程

如果对象当前是不可连接的,它将获得rhs表示的执行线程(如果有的话)。

如果它是可接合的,则调用terminate()。

调用之后,rhs不再表示任何执行线程(就像默认构造的线程一样)。

线程对象不能被复制(2)。

 

rhs - thread object whose state is moved to *this.

 

获取线程id

id get_id() const noexcept;

返回线程id。

如果线程对象是可接合的,函数返回唯一标识线程的值。

如果线程对象是不可连接的,该函数返回一个默认构造的成员类型为thread::id的对象。

 

No-throw保证:从不抛出异常。

 

检查是否可接合的

bool joinable() const noexcept;

返回线程对象是否可接合。

如果线程对象表示一个执行线程,那么它是可接合的。

线程对象在以下任何一种情况下都是不可连接的:

  • 如果它是默认构造的。
  • 如果它已被移动(构造另一个线程对象,或对其进行赋值)。
  • 如果它的任何一个成员被调用join或detach。

 

连接线程

void join();

当线程执行完成时,函数返回。

这将在函数返回的时刻与线程中所有操作的完成同步:这将阻塞调用该函数的线程的执行,直到被调用的构造函数返回(如果它还没有返回)。

调用此函数后,线程对象变得不可接合,可以安全地销毁。

 

完成对象的修改。

注意,线程对象本身的任何操作都是不同步的(与它所代表的线程内的操作不同)。

 

异常:

基本保证:如果这个成员函数抛出异常,线程对象将保持有效状态。

如果调用失败,抛出一个system_error异常:

请注意,如果对象表示的线程以未捕获的异常终止,当前线程无法捕获该异常,并自动调用terminate()。

 

分离线程

void detach();

将对象表示的线程与调用线程分离,允许它们彼此独立地执行。

两个线程继续运行,不会阻塞也不会以任何方式同步。注意,当其中一个结束执行时,它的资源将被释放。

调用此函数后,线程对象变得不可接合,可以安全地销毁。

 

异常:

基本保证:如果这个成员函数抛出异常,线程对象将保持有效状态。

如果调用失败,抛出一个system_error异常:

 

交换线程

void swap (thread& x) noexcept;

用x的状态交换对象的状态。

x - 线程对象,其状态被交换为*this的状态。

 

获取本地处理

native_handle_type native_handle ();

只有库实现支持时,这个成员函数才会出现在类thread中。

如果存在,则返回一个用于访问与线程相关的特定于实现的信息的值。

 

检测硬件并发

static unsigned hardware_concurrency() noexcept;

返回硬件线程上下文的数目。

对这个值的解释是特定于系统和实现的,可能不精确,但只是一个近似。

注意,这并不需要与系统中可用的处理器或内核的实际数量匹配:一个系统可以支持每个处理单元多个线程,或者限制程序对其资源的访问。

如果此值不可计算或定义不当,则函数返回0。

 

返回值

关于硬件线程上下文数量的提示。

如果该值不可计算或定义不明确,则为零。

 

交换线程(非成员重载)

void swap (thread& x, thread& y) noexcept;

交换线程对象x和y的状态。

这是一个swap重载,其行为就像调用了x.swap(y)。

 

x, y - 交换的线程对象。

 

namespace std::this_thread

这个名称空间将一组访问当前线程的函数分组。

 

  • get_id

获取线程id,返回调用线程的线程id。

这个值唯一地标识线程。

 

  • yield

void yield() noexcept;

让步于其他线程,调用线程产生,为实现提供了重新调度的机会。

当一个线程等待其他线程在不阻塞的情况下前进时,将调用这个函数。

 

  • sleep_until

template <class Clock, class Duration>

  void sleep_until (const chrono::time_point<Clock,Duration>& abs_time);

Sleep 直到指定时间点,阻塞调用线程直到abs_time。

当前线程的执行至少停止到abs_time,而其他线程可以继续前进。

 

  • sleep_for

template <class Rep, class Period>

  void sleep_for (const chrono::duration<Rep,Period>& rel_time);

Sleep 指定时间跨度

在rel_time指定的时间范围内阻塞调用线程的执行。当前线程的执行将停止,直到至少rel_time已经通过。其他线程继续执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值