C++ std::thread概念介绍
2020-12-13 14:44
标签:之间 equal 线程并发 区别 this erro 而且 就是 detach C++ 11新标准中,正式的为该语言引入了多线程概念。新标准提供了一个线程库thread,通过创建一个thread对象来管理C++程序中的多线程。 本文简单聊一下C++多线程相关的一些概念及thread的基本用法。 程序并行执行两个必要条件: 软件并发执行可分为两大类: 对于多线程,主要关注的是线程间的同步措施,用于确保线程安全; 对于多进程,主要关注的是进程间的通信机制,用于进程间传递消息和数据; 由于C++ 标准中没有多进程之间通信相关的标准,这些只能依赖于特定平台的API。本文只关注多线程相关。 C++11之前,window和linux平台分别有各自的多线程标准。使用C++编写的多线程往往是依赖于特定平台的。 在C++11新标准中,可以简单通过使用hread库,来管理多线程。thread库可以看做对不同平台多线程API的一层包装; 因此使用新标准提供的线程库编写的程序是跨平台的。 pthreads 是linux下的C++线程库,提供了一些线程相关的操作,比较偏向于底层,对线程的操作也是比较直接和方便的; linux上对于pthread的使用需要连接pthread库(有些编辑器可能需要 -std=c++11): 尽管网上对C++ 11新标准中的thread类有很多吐槽,但是作为C++第一个标准线程库,还是有一些值得肯定的地方的,比如跨平台,使用简单。 而且新标准中可以方便的使用RAII来实现lock的管理等。 如果你想深入研究一下多线程,那么pthread是一个不错的选择。如果想要跨平台或者实现一些简单的多线程场景而不过多关注细节,那么权威的标准库thread是不二之选。 总之没有好与坏之分,适合就好。可以的话可以都了解一下。本文主要介绍后者。 对于多线程相关的学习,先弄清楚线程相关的一些概念,是很重要的。 比如线程安全、线程同步与互斥关系、线程如何通信、与进程的关系如何等。 不然实际写多线程程序是会碰到太多的问题,例如: 光线程安全就有很多理论要了解,这些光靠调试程序,根据结果来猜测是不可行的。 关于多线程相关的概念可以参考我之前以Python为例介绍线程的博文: 看一下C++11 使用标准库thread创建多线程的例子: 多线程标准库使用一个thread的对象来管理产生的线程。该例子中线程对象t表示新建的线程。 打开thread头文件,可以清楚的看到thread提供的构造函数。 其中拷贝构造函数和拷贝赋值运算符被禁用,意味着std::thread对象不能够被拷贝和赋值到别的thread对象; 默认构造函数构造一个空的thread对象,但是不表示任何线程; 接受参数的构造函数创建一个表示线程的对象,线程从传入的函数开始执行,该对象是joinable的; move构造函数可以看做将一个thread对象对线程的控制权限转移到另一个thread对象;执行之后,传入的thread对象不表示任何线程; 多数情况下我们使用的是上面第二种创建线程的方式。下面看一下join和detach。 对于创建的线程,一般会在其销毁前调用join和detach函数; 弄清楚这两个函数的调用时机和意义,以及调用前后线程状态的变化非常重要。 join实例分析: 简单来说就是只有处于活动状态的线程才可以调用join,调用返回表示线程执行完毕,joinable() == false. 将上面的t.join()换成是t.detach()会得到相同的结果. 上面是thread文件中对detach的定义,可以看出只有joinable() == true的线程,也就是活动状态的线程才可以调用detach。 当线程既没有调用join也没有调用detach的时候,线程执行完毕joinable() == true,那么当thread对象被销毁的时候,会调用terminate()。 线程ID是一个线程的标识符,C++标准中提供两种方式获取线程ID; 有一点需要注意,就是空thread对象,也就是不表示任何线程的thread obj调用get_id返回值为0; 此外当一个线程被detach或者joinable() == false时,调用get_id的返回结果也为0。 除了上面介绍的detach可以分离thread对象及其所表示的线程,或者move到别的线程之外,还可以使用swap来交换两个thread对象表示的线程。 实例来看一下两个线程的交换。 结果: 下面是thread::swap函数的实现。 可以看到交换的过程仅仅是互换了thread对象所持有的底层句柄; 关于C++ 多线程新标准thread的基本介绍就到这里了,看到这里应该有一个简单的认识了。 关于线程安全和管理等高级话题,后面有空在写文章介绍。 C++ std::thread概念介绍 标签:之间 equal 线程并发 区别 this erro 而且 就是 detach 原文地址:https://www.cnblogs.com/yssjun/p/11533346.html0. 并行执行
1. C++多线程平台
2. pthread 或 C++ 11 thread
#include
g++ source.cpp -lpthread -o source.o
3. 先理论后实践
4. thread 多线程实例
1 #include
4.1 标准库创建线程的方式
int main()
{
int arg = 0;
std::thread t1; // t1 is not represent a thread
std::thread t2(func1, arg + 1); // pass to thread by value
std::thread t3(func2, std::ref(arg)); // pass to thread by reference
std::thread t4(std::move(t3)); // t4 is now running func2(). t3 is no longer a thread
//t1.join() Error!
t2.join();
//t3.join() Error!
t4.join();
}
4.2 join && detach
int main() {
thread t(tstart, "C++ 11 thread!");
cout endl;
if (t.joinable()) t.join();
//t.detach(); Error
cout endl;
// t.join(); Error
cout "Main Function!" endl;
system("pause");
}
inline void thread::join()
{ // join thread
if (!joinable())
_Throw_Cpp_error(_INVALID_ARGUMENT);
const bool _Is_null = _Thr_is_null(_Thr); // Avoid Clang -Wparentheses-equality
... ...
}
void detach()
{ // detach thread
if (!joinable())
_Throw_Cpp_error(_INVALID_ARGUMENT);
_Thrd_detachX(_Thr);
_Thr_set_null(_Thr);
}
~thread() _NOEXCEPT
{ // clean up
if (joinable())
_XSTD terminate();
}
4.3 获取线程ID
cout ‘ ‘ endl;
//t.detach();
t.join();
cout ‘ ‘
4.4 交换thread表示的线程
int tstart(const string& tname) {
cout "Thread test! " endl;
return 0;
}
int main() {
thread t1(tstart, "C++ 11 thread_1!");
thread t2(tstart, "C++ 11 thread_2!");
cout "current thread id: " endl;
cout "before swap: "" thread_1 id: " " thread_2 id: " endl;
t1.swap(t2);
cout "after swap: " " thread_1 id: " " thread_2 id: " endl;
//t.detach();
t1.join();
t2.join();
}
Thread test! C++ 11 thread_1!
Thread test! C++ 11 thread_2!
current thread id: 39308
before swap: thread_1 id: 26240 thread_2 id: 37276
after swap: thread_1 id: 37276 thread_2 id: 26240
void swap(thread& _Other) _NOEXCEPT
{ // swap with _Other
_STD swap(_Thr, _Other._Thr);
}
上一篇:WinMerge文件编码设置
文章标题:C++ std::thread概念介绍
文章链接:http://soscw.com/index.php/essay/34421.html