深圳网站建设.-方维网络,齐齐哈尔做网站公司,网站设计介绍,android 写wordpressthread
std::thread 类代表一个单独的执行线程。在创建与线程对象相关联时#xff0c;线程会立即开始执行#xff08;在等待操作系统调度的延迟之后#xff09;#xff0c;从构造函数参数中提供的顶层函数开始执行。顶层函数的返回值被忽略#xff0c;如果它通过抛出异常…thread
std::thread 类代表一个单独的执行线程。在创建与线程对象相关联时线程会立即开始执行在等待操作系统调度的延迟之后从构造函数参数中提供的顶层函数开始执行。顶层函数的返回值被忽略如果它通过抛出异常终止则会调用 std::terminate。
std::thread 对象也可以处于不表示任何线程的状态默认构造、移动、分离或加入之后而且执行线程可能不与任何 std::thread 对象关联分离之后。
std::thread 不可复制构造或复制赋值但是可以移动构造和移动赋值。
构造函数
默认构造函数。创建一个不表示任何线程的新的std::thread对象。移动构造函数。将 other 所表示的线程转移给新的 std::thread 对象。在此调用后other 不再表示一个线程。创建一个新的 std::thread 对象并将其与一个线程关联起来且新的线程开始执行。
析构函数
销毁线程对象。 如果 *this 有关联的线程 (joinable() true)则调用 std::terminate()。
移动构造函数
如果 *this 仍然关联着一个正在运行的线程即 joinable() true则调用 std::terminate() 终止程序。否则将 other 的状态赋值给 *this并将 other 设为默认构造状态。
Observers
joinable:
joinable() 函数用于检查 std::thread 对象是否标识着一个活动的执行线程。一个默认构造的线程是不可结合joinable的。
get_id:
返回 std::thread::id 的值。
native_handle:
返回实现定义的底层线程句柄。对于LInux系统来说就是返回一个Linux系统中定义的线程类型值。
hardware_concurrency(static):
返回实现支持的并发线程数。该值应仅被视为提示。
Operations:
join:
阻塞当前线程直到由 *this 标识的线程执行完成。
detach:
将执行线程与线程对象分开允许独立继续执行。调用 detach *this 后不再拥有任何线程。
swap:
交换两个线程对象的底层句柄
Non-member functions:
std::swap:
重载了次类的std::swap算法其实现相当于调用成员函数swap。
管理线程的非成员函数
std::this_thread::yield();
重新调度线程的执行让其他线程运行。
std::this_thread:get_id();
返回当前线程的id。
std::this_thread::sleep_for();
阻塞当前线程的执行至少持续指定的 sleep_duration。
由于调度或资源争用延迟的原因此函数可能会阻塞的时间超过 sleep_duration。
std::sleep_until();
阻塞当前线程的执行直到达到指定的 sleep_time。
锁
std::mutex
互斥锁 一种独占性资源因此没有复制构造函数和复制运算符。线程通过调用它的成员函数lock或try_lock才能拥有该互斥量。如果一个互斥量在任何线程仍然拥有它的情况下被销毁或者一个线程在拥有互斥量时终止程序的行为是未定义的。
Member types
构造函数
只有默认构造函数。复制构造函数被删除。也没有移动构造函数。
Locking
lock
对互斥量加锁。
try_lock:
尝试锁定互斥锁。立即返回成功锁定后返回true否则返回false。
unlock:
对互斥锁解决。
Native handle:
native_handle();
返回底层实现定义的本地句柄对象。
std::timed_mutex
timed_mutex 提供了mutex的全部功能除此之外还提供了超时的情况下锁的是否锁定的问题。在Linux系统中它和std::mutex的native_handle()的返回值是一样的。
它提供了std::mutex的全部的成员函数。以下是std::mutex没有的两个成员函数。
Locking
try_lock_for:
尝试锁定互斥。阻塞直到指定的持续时间 timeout_duration 已过超时或锁被获取拥有互斥以先到者为准。成功获取锁后返回 true否则返回 false。
try_lock_until:
尝试锁定互斥量。阻塞直到达到指定的超时时间timeout_time或成功获取锁定拥有互斥量以先到者为准。成功获取锁定时返回 true否则返回 false。
如果超时时间已经过去此函数的行为类似于 try_lock()。
std::shared_mutex
shared_mutex 具有两个级别的访问权限
共享访问多个线程可以共享对同一个互斥量的拥有权。独占访问只有一个线程可以拥有互斥量。
在同一个线程内同一时间只能获取一个锁共享锁或独占锁。它不能被拷贝。
构造函数
默认构造函数没有拷贝构造函数和移动构造函数。
没有赋值运算符。
Exclusive locking
lock:
获得对 shared_mutex 的独占所有权。如果另一个线程在同一个 shared_mutex 上持有独占锁或共享锁调用锁定将阻塞执行直到所有此类锁都被释放。当 shared_mutex 以独占模式锁定时不能同时持有其他任何类型的锁。
try_lock:
尝试锁定互斥。立即返回。成功锁定后返回 true否则返回 false。即使当前互斥项未被任何其他线程锁定该函数也允许假失败并返回 false。如果 try_lock 被一个已经在任何模式共享或独占下拥有该互斥项的线程调用其行为将是未定义的。
unlock:
对此锁解锁。
shared locking:
lock_shared:
获取互斥项的共享所有权。
try_lock_shared:
尝试在共享模式下锁定互斥。立即返回。成功锁定后返回 true否则返回 false。即使互斥当前未被任何其他线程独占锁定该函数也允许错误地失败并返回 false。
unlock_shared:
从调用线程的共享所有权中释放互斥。在共享模式下mutex 必须被当前执行线程锁定否则其行为将是未定义的。
std::shared_timed_mutex
和std::shared_mutex相似相比于它没有native_handle()这样获取底层资源的函数且多了这四个参数
try_lock_for:
尝试获取互斥量的锁。阻塞直到指定的持续时间 timeout_duration 经过超时或者成功获取锁拥有互斥量以先到者为准。如果成功获取锁则返回 true否则返回 false。由于调度或资源争用延迟此函数可能会阻塞超过 timeout_duration 的时间。与 try_lock() 类似即使在 timeout_duration 的某个时间点上互斥量没有被其他线程锁定此函数也可以出现虚假失败并返回 false。
try_lock_until:
尝试获取互斥量的锁。阻塞直到达到指定的超时时间 timeout_time到达超时或成功获取锁拥有互斥量以先到者为准。如果成功获取锁则返回 true否则返回 false。如果超时时间 timeout_time 已经过去则此函数的行为类似于 try_lock()。与 try_lock() 类似即使在超时时间之前互斥量没有被其他线程锁定该函数也可以出现虚假失败并返回 false。
try_lock_shared_for:
与try_lock_for类似只是获取的是共享锁。
try_lock_shared_until:
与try_lock_until类似只是获取的是共享锁。
锁管理
std::lock_guard
lock_guard 类是一个互斥包装器, 当创建 lock_guard 对象时它会尝试获取所给互斥的所有权。当控制权离开创建 lock_guard 对象的作用域时lock_guard 会被析构mutex 也会被释放。lock_guard类不可被拷贝没有赋值运算符。
它的模板参数必须符合BasicLockable要求。
构造函数
接受一个锁参数然后立刻调用其lock()成员函数。获取 mutex m 的所有权但不试图锁定它。如果当前线程未持有 m 上的非共享锁则该行为未定义。
析构函数
调用拥有的锁的unlock()。
std::unique_lock
类unique_lock是一个通用的互斥量所有权包装器允许延迟锁定、限时尝试锁定、递归锁定、锁的所有权转移以及与条件变量一起使用。类unique_lock是可移动的但不可复制。
构造函数
默认构造函数构造一个没有关联互斥量的对象。移动构造函数用其他对象的内容初始化unique_lock对象同时将其他对象置为没有关联互斥量。使用互斥量m构造一个关联的unique_lock对象然后可以通过选择是否传参以及传递什么参数使互斥量被锁定、不锁定、调用try_lock()锁定、认为互斥量是非共享锁定状态的、调用try_lock_for或调用try_lock_until的。
析构函数
如果 *this 有关联的互锁体并且已获得其所有权则互锁体被解锁。
移动赋值操作符
使用移动语义将内容替换为其他内容。如果在调用 *this 之前已关联了一个互斥项并获得了它的所有权则互斥项将被解锁。
Locking
lock
锁定拥有的互斥。实际上是调用拥有互斥的lock成员函数。
try_lock:
尝试在不阻塞的情况下锁定即获取相关的互斥。实际上是调用 mutex()-try_lock()。
try_lock_for:
实际上调用了 mutex()-try_lock_for(timeout_duration)。
try_lock_until:
实际上调用了 mutex()-try_lock_until(timeout_time)。
unlock:
解锁。实际上调用了mutex()-unlock();
Modifiers:
swap;
交换锁对象的内部状态。
release():
中断相关互斥如果有与 *this 的关联。不会解锁任何锁。
Observers:
mutex();
返回指向相关静态代理的指针如果没有相关静态代理则返回空指针。
owns_lock();
检查 *this 是否拥有锁定的互斥。
std::shared_lock
类shared_lock是一个通用的共享互斥量所有权包装器允许延迟锁定、定时锁定和锁的所有权转移。通过对shared_lock进行锁定将以共享模式锁定关联的共享互斥量. shared_lock类是可移动的但不可复制。
构造函数
默认构造函数构造一个没有关联互斥量的对象。移动构造函数用其他对象的内容初始化shared_lock对象同时将其他对象置为没有关联互斥量。使用互斥量m构造一个关联的shared_lock对象然后可以通过选择是否传参以及传递什么参数使互斥量以共享模式被锁定、不锁定、调用try_lock_shared()锁定、认为互斥量是共享锁定状态的、调用try_lock_shared_for或调用try_lock_shared_until的。
析构函数
如果 *this 有关联的互锁体并且已获得其所有权则通过调用 unlock_shared() 来解锁互锁体。
赋值运算符
使用移动语义将内容替换为其他内容。如果在调用 *this 之前已关联了一个互斥项并获得了它的所有权则会通过调用 unlock_shared() 来解锁互斥体。
Locking
lock
以共享模式锁定相关的互斥。实际上是调用拥有互斥的lock_shared成员函数。
try_lock:
尝试在不阻塞的情况下以共享模式锁定相关的互斥。实际上是调用 mutex()-try_lock_shared()。
try_lock_for:
实际上调用了 mutex()-try_lock_shared_for(timeout_duration)。
try_lock_until:
实际上调用了 mutex()-try_lock_shared_until(timeout_time)。
unlock:
解锁。实际上调用了mutex()-unlock_shared();
Modifiers:
swap;
交换锁对象的内部状态。
release():
中断相关互斥如果有与 *this 的关联。不会解锁任何锁。
Observers:
mutex();
返回指向相关静态代理的指针如果没有相关静态代理则返回空指针。
owns_lock();
检查 *this 是否拥有共享互斥量的共享所有权。
std::scoped_lock
类scoped_lock是一个互斥量包装器, 用于在作用域块的持续时间内拥有零个或多个互斥量。如果给定了多个互斥量则会使用避免死锁的算法类似于std::lock的行为。scoped_lock类是不可复制的。
构造函数
获取给定互斥量的所有权即调用对应的lock成员函数。在不尝试锁定任何互斥量的情况下获取互斥量 m... 的所有权。除非当前线程对 m... 中的每个对象都持有非共享锁否则行为是未定义的。
析构函数
释放所有互斥的所有权及调用每个互斥体的unlock()成员函数。
赋值运算符已经被删除。
Call once
call_once:
once_flag:
Condition variables
条件变量的唤醒丢失与虚假唤醒问题。
std::condition_variable
condition_variable 类是与 std::mutex 一起使用的同步原语用于阻塞一个或多个线程直到另一个线程修改了共享变量条件并通知 condition_variable。std::condition_variable仅适用于std::unique_lockstd::mutex这样可以在某些平台上实现最高效率。
它不可被移动或复制。
构造函数
默认构造函数构造一个std::condition_variable对象。
析构函数
销毁 std::condition_variable 类型的对象。只有在所有线程都已被通知的情况下才能安全地调用析构函数。
Notification
notify_one():
如果有线程正在等待 *this调用 notify_one 会解除其中一个等待线程的阻塞。
notify_all():
解除当前等待 *this 的所有线程的阻塞。
Waiting:
wait:
wait 函数会导致当前线程阻塞直到条件变量被通知或出现虚假唤醒。它有两个重载。
只有参数锁原子性地解锁 lock阻塞当前执行的线程并将其添加到等待 *this 的线程列表中。它被唤醒而解除阻塞时都会重新获取互斥锁并退出 wait 函数。有参数锁和谓词等价于如下代码
while (!stop_waiting()) { // stop_waiting函数是谓词wait(lock);
}这个重载函数可以避免虚假唤醒的问题。
这里的锁必须是std::unique_lockstd::mutex
wait_for: wait_until:
前者是最多阻塞的相对超时时间后者是最多阻塞到某个时间点。它们其余部分和wait一致。
Native handle
native_handle():访问 *this 的本地句柄。
std::condition_variable_any
class condition_variable_any 是 std::condition_variable 的一个更通用的版本。而 std::condition_variable 只能与 std::unique_lockstd::mutex 一起使用condition_variable_any 可以操作任何满足 BasicLockable 要求的锁。
class std::condition_variable_any 是一个 StandardLayoutType。它不可被移动或复制。
如果锁是 std::unique_lockstd::mutex则 std::condition_variable 可能提供更好的性能。
下面列出些std::condition_variable没有的功能
waitwait_for; wait_until
都多了第三个重载多了一个stoken变量多了一个 std::stop_token 对象用于支持取消等待操作。当外部发出取消请求时可以通过该对象检查并中止等待。
Latches and Barriers
Futures
Futures 功能是并发编程机制旨在简化多线程编程和异步操作的处理。Futures 提供了一种在一个线程中计算值或执行任务并在另一个线程中获取结果的方法。
它的核心组件时std::future 和 std::promise 。std::future 对象与 std::promise 对象之间共享一个状态。通过 std::promise 对象设置的值可以通过与其关联的 std::future 对象来获取。这样就可以使一个线程使用 std::promise 对象来设置异步操作的结果而另一个线程使用对应的 std::future 对象来获取结果。
std::futuer
std::future提供了一种访问异步操作结果的机制, 通过std::async、std::packaged_task或std::promise创建的异步操作可以向该异步操作的创建者提供一个std::future对象。异步操作的创建者可以使用各种方法来查询、等待或从std::future中提取值。
构造函数
默认构造函数创建一个没有共享状态的 std::future 对象。移动构造函数构造后被移动的对象没有共享状态拷贝构造函数被删除。
析构函数
释放任何共享状态不会阻塞等待共享状态变为就绪除非以下所有条件都成立时可能会阻塞一定会阻塞吗
共享状态是通过调用 std::async 创建的。共享状态尚未就绪。当前对象是对共享状态的最后一个引用。
这些操作只有在任务的启动策略为 std::launch::async 时才会阻塞
只有移动赋值运算符没有拷贝赋值运算符。移动后被移动的对象没有共享状态。
share():
将 *this 的共享状态如果有的话转移给一个 std::shared_future 对象。在调用 share 后valid() false。
Getting the result:
get():
阻塞当前线程直到future准备妥当并返回该值或者抛出异步运行的函数的异常或被设置的异常. 在调用此成员函数后共享状态会被释放, valid() 为 false。如果在调用此函数之前 valid() 为 false则行为是未定义的。
State:
valid:
检查 future 是否引用共享状态。
wait:
阻塞直到结果变为可用。
wait_for:
等待结果变为可用。阻塞直到指定的 timeout_duration 经过或结果可用以先到者为准。返回值标识结果的状态。如果 future 是通过使用lazy evaluation的方式调用 std::async 的结果该函数会立即返回而不等待。
wait_until:
wait_until 函数等待结果变为可用。它会阻塞直到达到指定的 timeout_time 或结果可用以先到者为准。返回值指示 wait_until 返回的原因。如果 future 是通过使用lazy evaluation的方式调用 std::async 的结果该函数会立即返回而不等待。
std::shared_future
std::shared_future类似于 std::future但允许多个线程等待相同的共享状态。std::shared_future 是既可移动也可复制的多个共享的 std::shared_future 对象可以引用相同的共享状态。通过各自的 std::shared_future 对象多个线程可以安全地访问相同的共享状态。
构造函数
默认构造函数。构造一个空的shared_future, 不引用共享状态。拷贝构造函数构造一个引用与other相同共享状态如果有的话的shared_future.移动构造函数将 other 持有的共享状态转移给 *this。构造后other.valid() false且 this-valid() 的返回值与在构造之前 other.valid() 的返回值相同。
赋值运算符
拷贝赋值运算符1. 释放任何共享状态并将 other 的内容赋值给 *this。赋值后this-valid() other.valid()。移动赋值运算符1. 释放任何共享状态并将 other 的内容移动赋值给 *this。赋值后other.valid() false并且 this-valid() 的返回值与赋值之前的 other.valid() 的返回值相同。
Getting the result:
get:
get 成员函数会等待直到 shared_future 有一个有效的结果并且根据使用的模板获取它。它实际上会调用 wait() 来等待结果。与 std::future 不同当调用 get() 时std::shared_future 的共享状态不会无效。
State:
valid();
检查 shared_future 是否引用共享状态。
wait():
调用后 valid() true。如果在调用此函数之前 valid() false则行为未定义。
wait_for();
等待结果可用。阻塞直到指定的 timeout_duration 已过或结果可用以先到者为准。返回值标识结果的状态。如果 future 是调用 std::async 并使用了懒评估的结果则此函数无需等待立即返回。
wait_until();
wait_until 等待结果可用。它会阻塞直到达到指定的 timeout_time 或结果可用为止以先到者为准。返回值说明 wait_until 返回的原因。如果 future 是调用 async 时使用了懒评估的结果则此函数会立即返回而无需等待。
std::async()
函数模板 std::async 异步地运行函数 f可能在一个独立的线程中该线程可能是线程池的一部分并返回一个 std::future最终将保存该函数调用的结果。它可以根据系统情况自动选择是独立启动一个线程运行还是在对应的future调用get时运行也可以由调用者指定任务调用策略。
任务调用策略
std::launch::async; 开启一个独立线程执行任务std::launch::deferred; 使用延迟批评估。
请注意除了调用 std::async 之外通过其他方式获得的 std::futures 的析构函数永远不会阻塞。
构造函数
不加策略的构造函数加策略的构造函数
std::package_task
类模板 std::packaged_task 可以封装任何可调用目标以便可以异步调用它。它的返回值或抛出的异常被存储在一个共享状态中可以通过 std::future 对象访问该状态。它不可被复制。
默认构造函数
构造一个没有任务和共享状态的 std::packaged_task 对象。构造一个具有共享状态和任务副本的 std::packaged_task 对象使用 std::forwardF(f) 进行初始化。复制构造函数被删除std::packaged_task 是只可移动的移动构造函数构造一个具有共享状态和任务的 std::packaged_task该状态和任务原先由 rhs 拥有将 rhs 置于无共享状态和已移动的任务状态。
析构函数
放弃共享状态并销毁存储的任务对象。如果共享状态在准备就绪之前被放弃则会存储一个 std::future_error 异常错误代码为 std::future_errc::broken_promise。
复制运算符
只有移动赋值运算符。移动赋值运算符释放共享状态如果有销毁之前持有的任务并将共享状态和 rhs 拥有的任务移入 *this。
valid();
检查是否有一个共享状态即是否包含一个有效的任务。
swap():
将*this和other的共享状态和存储的任务进行交换。
Getting the result:
get_future:
用于获取一个 std::future 对象该对象与当前 std::packaged_task 共享相同的共享状态。get_future() 函数只能调用一次.
Execution:
operator():
执行存储中的任务。任务的返回值或抛出的任何异常都会存储在共享状态中。
make_ready_at_thread_exit:
共享状态只有在当前线程退出并且所有具有线程局部存储期的对象被销毁后才会准备就绪。
reset():
重置状态放弃之前的执行结果。构建新的共享状态。
std::promise
类模板 std::promise 提供了一种存储值或异常的机制这些值或异常可以通过由 std::promise 对象创建的 std::future 对象在异步方式下获取。std::promise 对象只能使用一次因此不可被复制。
每个 promise 关联一个共享状态, 它可以对共享状态执行三种操作
准备就绪 promise 将结果或异常存储在共享状态中。标记状态为就绪并解除任何等待与共享状态相关联的 future 的线程的阻塞。释放 promise 放弃对共享状态的引用。如果这是最后一个对共享状态的引用那么共享状态将被销毁。放弃 promise 将类型为 std::future_error错误代码为 std::future_errc::broken_promise 的异常存储在共享状态中使共享状态变为就绪状态然后释放它。
构造函数拷贝构造函数被删除
默认构造函数。使用空的共享状态构造promise。移动构造函数。使用移动语义构造 promise使用其他 promise 的共享状态。构造完成后其他 promise 不再具有共享状态。
析构函数
如果共享状态已就绪则释放共享状态。如果共享状态未就绪则存储一个 std::future_error 类型的异常对象错误条件为 std::future_errc::broken_promise使共享状态就绪并释放它。
赋值运算符没有拷贝运算符
移动赋值操作符。首先放弃共享状态然后通过执行 std::promise(std::move(other)).swap(*this) 赋值给 other 的共享状态。
Getting the result:
get_future:
返回与 *this 相同共享状态相关联的std::future。
set_value; set_value_at_thread_exit;
原子式地将值存储到共享状态中并使状态就绪。如果没有共享状态或共享状态已存储值或异常则会抛出异常。
前者是立即让共享状态就绪后者是等当前线程退出时所有具有线程本地存储期限的变量都已销毁状态才会就绪。
set_exception; set_exception_at_thread_exit;
除了存储的是异常其余和set_value; set_value_at_thread_exit;完全一致。
set_value: 保存值
set_exception: 保存异常