注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

C++11及BOOST特性之二线程之一创建线程  

2013-12-05 22:24:05|  分类: C++(VC)编程 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

C++11BOOST特性之二线程之一创建线程

无论在WIN下还是在LINUX下,创建线程都比较麻烦,无数的线程创建函数,再加上线程运行的函数,以及内部的参数,让你会眼花缭乱。多么希望能有一个标准的线程库函数啊。C++11现在提供了这个库,虽然还很稚嫩,但是这是一个非常好的开始。

在使用这个线程库时,一定要注意一些问题。原来无论使用哪上线程创建函数,都不涉及到变量的范围的问题,可是在这个库里,就有这个问题了。举一个例子:

在一个类的成员函数中:

Void ThreadFun(std:string s)

{

While(1)

{

…..

}

}

Std::thread oktest;

Void Test::TestThreadCreate()

{

    Oktest = std::thread(ThreadFun,”test”);  //第一种情况

         Std::thread test(ThreadFun,”test”);      //第二种情况

    Std::test.join();

}

在上面的第二种情况中,线程会异常的退出,因为定义了一个局部的线程类对象,在函数结果后,自动销毁,然后程序自然就挂了。即使你增加了join等待,照样也是如此。而第一种情况就没有问题。因为他是一个全局变量,当然,换一个思路,给成类的的成员变量,在类的生存期内也是没有问题的。不过,这仍然存在着堆栈和文件描述符的泄露。

这就引出下面的一个问题,就是joinable问题,在C++11中:

A thread object is not joinable in any of these cases:

?if it was default-constructed.

?if it has been moved from (either constructing another thread object, or assigning to it).

?if either of its members join or detach has been called.

帮助文档说得很清楚,只有上面三种情况是非joinable的,也就是说,不需要主程序或者其它线程使用t.join(),LINUX中使用pthread_join(id,NULL))去等待.

而在LINUX中创建线程是可以利用参数来控制:

pthread_create(&id, NULL, FUN, NULL);第二个参数为NULL(表示PTHREAD_CREATE_JOINABLE),表示为可joinable的。否则设置为PTHREAD_CREATE_DETACHED。同样,上面也已经注明了,也可以在主程序里pthread_join(id,NULL)或者在线程函数内:pthread_join(pthread_detach(pthread_self()))

 

再引申一层,如果你的线程创建被封装到了一个类里,比如:

class MyThread

{

public:

         std::thread td;

public:

         void static tdTest(){ while (1)

         {

                   t++;

         }

         }

         void Create()

         {

                   td = std::thread(tdTest);

                   //td.detach();//注意这里

         }

};

也就是说,只 在上面的线程中增加了detach这个函数,那么即何在第二种情况下也没有问题。这就可以总结一下:

joinable状态下,当线程函数自己返回退出时或pthread_exit时都不会释放线程所占用堆栈和线程描述符。只有当你调用了pthread_join之后这些资源才会被释放,这是需要main函数或者其他线程去调用pthread_join函数。unjoinable状态的线程,这些资源在线程函数退出时或pthread_exit时自动会被释放。设置unjoinable状态设置有两种办法 一是可以在pthread_create时指定,二是线程创建后在线程中pthread_detach自己。这在上面已经介绍过了。

还有两个小小的注意点:

std::thread t3(f2, std::ref(n)); // pass by reference

std::thread t4(std::move(t3)); // t4 is now running f2(). t3 is no longer a thread

线程的引用传参使用ref,常用的&符号因为模板的原因无法使用了。另外一个是move右值传参的例子。

书到用时方恨少,事非经过不知难。

  评论这张
 
阅读(536)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017