求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 


业务架构设计
4月18-19日 在线直播



基于UML和EA进行系统分析设计
4月25-26日 北京+在线



AI 智能化软件测试方法与实践
5月23-24日 上海+在线
 
追随技术信仰

随时听讲座
每天看新闻
 
 
C++并发编程(中文版)
前言
第1章 你好,C++的并发世界!
1.1 何谓并发
1.2 为什么使用并发?
1.3 C++中的并发和多线程
1.4 开始入门
1.5 本章总结
第2章 线程管理
2.1 线程管理的基础
2.2 向线程函数传递参数
2.3 转移线程所有权
2.4 运行时决定线程数量
2.5 识别线程
2.6 本章总结
第3章 线程间共享数据
3.1 共享数据带来的问题
3.2 使用互斥量保护共享数据
3.3 保护共享数据的替代设施
3.4 本章总结
第4章 同步并发操作
4.1 等待一个事件或其他条件
4.2 使用期望等待一次性事件
4.3 限定等待时间
4.4 使用同步操作简化代码
4.5 本章总结
第5章 C++内存模型和原子类型操作
5.1 内存模型基础
5.2 C++中的原子操作和原子类型
5.3 同步操作和强制排序
5.4 本章总结
第6章 基于锁的并发数据结构设计
6.1 为并发设计的意义何在?
6.2 基于锁的并发数据结构
6.3 基于锁设计更加复杂的数据结构
6.4 本章总结
第7章 无锁并发数据结构设计
7.1 定义和意义
7.2 无锁数据结构的例子
7.3 对于设计无锁数据结构的指导建议
7.4 本章总结
第8章 并发代码设计
8.1 线程间划分工作的技术
8.2 影响并发代码性能的因素
8.3 为多线程性能设计数据结构
8.4 设计并发代码的注意事项
8.5 在实践中设计并发代码
8.6 本章总结
第9章 高级线程管理
9.1 线程池
9.2 中断线程
9.3 本章总结
第10章 多线程程序的测试和调试
10.1 与并发相关的错误类型
10.2 定位并发错误的技术
10.3 本章总结
附录A C++11语言特性简明参考(部分)
A .1 右值引用
A .2 删除函数
A .3 默认函数
A .4 常量表达式函数
A .5 Lambda函数
A .6 变参模板
A .7 自动推导变量类型
A .8 线程本地变量
A .9 本章总结
附录B 并发库的简单比较
附录C 消息传递框架与完整的ATM示例
 附录D C++线程库参考
D .1 chrono头文件
D .2 <condition_variable>头文件
D .3 <atomic>头文件
D .4 future头文件
D .5 <mutex>头文件
D .6 <ratio>头文件
D .7 <thread>头文件
 

 
目录
<thread>头文件
作者:Anthony Williams  译者:陈晓伟
115 次浏览
9次  

D.7 thread头文件

<thread>头文件提供了管理和辨别线程的工具,并且提供函数,可让当前线程休眠。

头文件内容

  1. namespace std
  2. {
  3. class thread;
  4. namespace this_thread
  5. {
  6. thread::id get_id() noexcept;
  7. void yield() noexcept;
  8. template<typename Rep,typename Period>
  9. void sleep_for(
  10. std::chrono::duration<Rep,Period> sleep_duration);
  11. template<typename Clock,typename Duration>
  12. void sleep_until(
  13. std::chrono::time_point<Clock,Duration> wake_time);
  14. }
  15. }

D.7.1 std::thread类

std::thread用来管理线程的执行。其提供让新的线程执行或执行,也提供对线程的识别,以及提供其他函数用于管理线程的执行。

  1. class thread
  2. {
  3. public:
  4. // Types
  5. class id;
  6. typedef implementation-defined native_handle_type; // optional
  7. // Construction and Destruction
  8. thread() noexcept;
  9. ~thread();
  10. template<typename Callable,typename Args...>
  11. explicit thread(Callable&& func,Args&&... args);
  12. // Copying and Moving
  13. thread(thread const& other) = delete;
  14. thread(thread&& other) noexcept;
  15. thread& operator=(thread const& other) = delete;
  16. thread& operator=(thread&& other) noexcept;
  17. void swap(thread& other) noexcept;
  18. void join();
  19. void detach();
  20. bool joinable() const noexcept;
  21. id get_id() const noexcept;
  22. native_handle_type native_handle();
  23. static unsigned hardware_concurrency() noexcept;
  24. };
  25. void swap(thread& lhs,thread& rhs);

 

std::thread::id 类

可以通过std::thread::id实例对执行线程进行识别。

类型定义

  1. class thread::id
  2. {
  3. public:
  4. id() noexcept;
  5. };
  6. bool operator==(thread::id x, thread::id y) noexcept;
  7. bool operator!=(thread::id x, thread::id y) noexcept;
  8. bool operator<(thread::id x, thread::id y) noexcept;
  9. bool operator<=(thread::id x, thread::id y) noexcept;
  10. bool operator>(thread::id x, thread::id y) noexcept;
  11. bool operator>=(thread::id x, thread::id y) noexcept;
  12. template<typename charT, typename traits>
  13. basic_ostream<charT, traits>&
  14. operator<< (basic_ostream<charT, traits>&& out, thread::id id);

 

std::thread::id的值可以识别不同的执行,每个std::thread::id默认构造出来的值都不一样,不同值代表不同的执行线程。

std::thread::id的值是不可预测的,在同一程序中的不同线程的id也不同。

std::thread::id是可以CopyConstructible(拷贝构造)和CopyAssignable(拷贝赋值),所以对于std::thread::id的拷贝和赋值是没有限制的。

std::thread::id 默认构造函数

构造一个std::thread::id对象,其不能表示任何执行线程。

声明

id() noexcept;

 

效果

构造一个std::thread::id实例,不能表示任何一个线程值。

抛出

NOTE 所有默认构造的std::thread::id实例存储的同一个值。

std::thread::id 相等比较操作

比较两个std::thread::id的值,看是两个执行线程是否相等。

声明

bool operator==(std::thread::id lhs,std::thread::id rhs) noexcept;

 

返回

当lhs和rhs表示同一个执行线程或两者不代表没有任何线程,则返回true。当lsh和rhs表示不同执行线程或其中一个代表一个执行线程,另一个不代表任何线程,则返回false。

抛出

std::thread::id 不相等比较操作

比较两个std::thread::id的值,看是两个执行线程是否相等。

声明

bool operator!=(std::thread::id lhs,std::thread::id rhs) noexcept;

 

返回

!(lhs==rhs)

抛出

std::thread::id 小于比较操作

比较两个std::thread::id的值,看是两个执行线程哪个先执行。

声明

bool operator<(std::thread::id lhs,std::thread::id rhs) noexcept;

 

返回

当lhs比rhs的线程ID靠前,则返回true。当lhs!=rhs,且lhs<rhs或rhs<lhs返回true,其他情况则返回false。当lhs==rhs,在lhs<rhs和rhs<lhs时返回false。

抛出

NOTE 当默认构造的std::thread::id实例,在不代表任何线程的时候,其值小于任何一个代表执行线程的实例。当两个实例相等,那么两个对象代表两个执行线程。任何一组不同的std::thread::id的值,是由同一序列构造,这与程序执行的顺序相同。同一个可执行程序可能有不同的执行顺序。

std::thread::id 小于等于比较操作

比较两个std::thread::id的值,看是两个执行线程的ID值是否相等,或其中一个先行。

声明

bool operator<(std::thread::id lhs,std::thread::id rhs) noexcept;

 

返回

!(rhs<lhs)

抛出

std::thread::id 大于比较操作

比较两个std::thread::id的值,看是两个执行线程的是后行的。

声明

bool operator>(std::thread::id lhs,std::thread::id rhs) noexcept;

 

返回

rhs<lhs

抛出

std::thread::id 大于等于比较操作

比较两个std::thread::id的值,看是两个执行线程的ID值是否相等,或其中一个后行。

声明

bool operator>=(std::thread::id lhs,std::thread::id rhs) noexcept;

返回

!(lhs<rhs)

抛出

std::thread::id 插入流操作

将std::thread::id的值通过给指定流写入字符串。

声明

  1. template<typename charT, typename traits>
  2. basic_ostream<charT, traits>&
  3. operator<< (basic_ostream<charT, traits>&& out, thread::id id);

效果

将std::thread::id的值通过给指定流插入字符串。

返回

NOTE 字符串的格式并未给定。std::thread::id实例具有相同的表达式时,是相同的;当实例表达式不同,则代表不同的线程。

std::thread::native_handler 成员函数

native_handle_type是由另一类型定义而来,这个类型会随着指定平台的API而变化。

声明

typedef implementation-defined native_handle_type;

 

NOTE 这个类型定义是可选的。如果提供,实现将使用原生平台指定的API,并提供合适的类型作为实现。

std::thread 默认构造函数

返回一个native_handle_type类型的值,这个值可以可以表示*this相关的执行线程。

声明

native_handle_type native_handle();

 

NOTE 这个函数是可选的。如果提供,会使用原生平台指定的API,并返回合适的值。

std::thread 构造函数

构造一个无相关线程的std::thread对象。

声明

thread() noexcept;

 

效果

构造一个无相关线程的std::thread实例。

后置条件

对于一个新构造的std::thread对象x,x.get_id() == id()。

抛出

std::thread 移动构造函数

将已存在std::thread对象的所有权,转移到新创建的对象中。

声明

thread(thread&& other) noexcept;

 

效果

构造一个std::thread实例。与other相关的执行线程的所有权,将转移到新创建的std::thread对象上。否则,新创建的std::thread对象将无任何相关执行线程。

后置条件

对于一个新构建的std::thread对象x来说,x.get_id()等价于未转移所有权时的other.get_id()。get_id()==id()。

抛出

NOTE std::thread对象是不可CopyConstructible(拷贝构造),所以该类没有拷贝构造函数,只有移动构造函数。

std::thread 析构函数

销毁std::thread对象。

声明

~thread();

 

效果

销毁*this。当*this与执行线程相关(this->joinable()将返回true),调用std::terminate()来终止程序。

抛出

std::thread 移动赋值操作

将一个std::thread的所有权,转移到另一个std::thread对象上。

声明

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

 

效果

在调用该函数前,this->joinable返回true,则调用std::terminate()来终止程序。当other在执行赋值前,具有相关的执行线程,那么执行线程现在就与*this相关联。否则,*this无相关执行线程。

后置条件

this->get_id()的值等于调用该函数前的other.get_id()。oter.get_id()==id()。

抛出

NOTE std::thread对象是不可CopyAssignable(拷贝赋值),所以该类没有拷贝赋值函数,只有移动赋值函数。

std::thread::swap 成员函数

将两个std::thread对象的所有权进行交换。

声明

void swap(thread& other) noexcept;

 

效果

当other在执行赋值前,具有相关的执行线程,那么执行线程现在就与*this相关联。否则,*this无相关执行线程。对于*this也是一样。

后置条件

this->get_id()的值等于调用该函数前的other.get_id()。other.get_id()的值等于没有调用函数前this->get_id()的值。

抛出

std::thread的非成员函数swap

将两个std::thread对象的所有权进行交换。

声明

void swap(thread& lhs,thread& rhs) noexcept;

 

效果

lhs.swap(rhs)

抛出

std::thread::joinable 成员函数

查询*this是否具有相关执行线程。

声明

bool joinable() const noexcept;

 

返回

如果*this具有相关执行线程,则返回true;否则,返回false。

抛出

std::thread::join 成员函数

等待*this相关的执行线程结束。

声明

void join();

 

先决条件

this->joinable()返回true。

效果

阻塞当前线程,直到与*this相关的执行线程执行结束。

后置条件

this->get_id()==id()。与*this先关的执行线程将在该函数调用后结束。

同步

想要在*this上成功的调用该函数,则需要依赖有joinable()的返回。

抛出

当效果没有达到或this->joinable()返回false,则抛出std::system_error异常。

std::thread::detach 成员函数

将*this上的相关线程进行分离。

声明

void detach();

 

先决条件

this->joinable()返回true。

效果

将*this上的相关线程进行分离。

后置条件

this->get_id()==id(), this->joinable()==false

与*this相关的执行线程在调用该函数后就会分离,并且不在会与当前std::thread对象再相关。

抛出

当效果没有达到或this->joinable()返回false,则抛出std::system_error异常。

std::thread::get_id 成员函数

返回std::thread::id的值来表示*this上相关执行线程。

声明

thread::id get_id() const noexcept;

 

返回

当*this具有相关执行线程,将返回std::thread::id作为识别当前函数的依据。否则,返回默认构造的std::thread::id。

抛出

std::thread::hardware_concurrency 静态成员函数

返回硬件上可以并发线程的数量。

声明

unsigned hardware_concurrency() noexcept;

 

返回

硬件上可以并发线程的数量。这个值可能是系统处理器的数量。当信息不用或只有定义,则该函数返回0。

抛出

D.7.2 this_thread命名空间

这里介绍一下std::this_thread命名空间内提供的函数操作。

this_thread::get_id 非成员函数

返回std::thread::id用来识别当前执行线程。

声明

thread::id get_id() noexcept;

 

返回

可通过std:thread::id来识别当前线程。

抛出

this_thread::yield 非成员函数

该函数用于通知库,调用线程不需要立即运行。一般使用小循环来避免消耗过多CPU时间。

声明

void yield() noexcept;

 

效果

使用标准库的实现来安排线程的一些事情。

抛出

this_thread::sleep_for 非成员函数

在指定的指定时长内,暂停执行当前线程。

声明

  1. template<typename Rep,typename Period>
  2. void sleep_for(std::chrono::duration<Rep,Period> const& relative_time);

效果

在超出relative_time的时长内,阻塞当前线程。

NOTE 线程可能阻塞的时间要长于指定时长。如果可能,逝去的时间由将会由一个稳定时钟决定。

抛出

this_thread::sleep_until 非成员函数

暂停指定当前线程,直到到了指定的时间点。

声明

  1. template<typename Clock,typename Duration>
  2. void sleep_until(
  3. std::chrono::time_point<Clock,Duration> const& absolute_time);

效果

在到达absolute_time的时间点前,阻塞当前线程,这个时间点由指定的Clock决定。

NOTE 这里不保证会阻塞多长时间,只有Clock::now()返回的时间等于或大于absolute_time时,阻塞的线程才能被解除阻塞。

抛出

 

 


您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码: 验证码,看不清楚?请点击刷新验证码 必填



115 次浏览
9次
下一页