std::thread(线程) 学习记录
发布日期:2022-02-06 00:27:07 浏览次数:17 分类:技术文章

本文共 4577 字,大约阅读时间需要 15 分钟。

std::thread(线程) 学习记录

1. thread的创建以及面临的问题

1.1 thread.cpp

//创建线程,C++中提供头文件thread,使用std的thread实例化一个线程对象的创建//std::thread在#include头文件中声明,因此使用std::thread需要包含#include头文件#include 
   
    #include 
    
     #include 
     
      using namespace std;void thread1(){

      
   for(int i = 0; i < 20; ++i)
{
   cout<<"thread1..."<
//cout<
}}void thread2(){
   for(int i = 0; i < 20; ++i)
{
   cout<<"thread2..."<
//cout<
}}int main(int argc, char* argv[]){
   google::InitGoogleLogging(argv[0]);
FLAGS_logtostderr = 1;
//设置只在终端打印信息
FLAGS_colorlogtostderr = 1;
thread th1(thread1);  //实例化一个线程对象th1,该线程开始执行
thread th2(thread2);
LOG(INFO)<<"main...";
return 0;
//结果分析:上例是有问题的,因为在创建了线程后,线程开始执行,但是主线程main()并没有停止脚步,仍然继续执行然后退出,
//此时线程对象还是joinable(可结合的),线程仍然存在但指向它的线程对象已经销毁,所以会中断.
//那么如何保证子线程执行完退出后再退出主线程呢?}

1.2 终端编译

在这里插入图片描述

1.3 编译结果

在这里插入图片描述

2. thread::join( )

2.1 thread.cpp

//解决方法之一:thread::join()//使用join接口可以解决上述问题,join的作用是让主线程等待直到该子线程执行结束.#include 
   
    #include 
    
     #include 
     
      using namespace std;void thread1(){

      
   for(int i = 0; i < 10; ++i)
{
   cout<<"thread1..."<
//cout<
}}void thread2(){
   for(int i = 0; i < 10; ++i)
{
   cout<<"thread2..."<
//cout<
}}int main(int argc, char* argv[]){
   google::InitGoogleLogging(argv[0]);
FLAGS_logtostderr = 1;
  //设置只在终端打印信息
FLAGS_colorlogtostderr = 1;
thread th1(thread1);  //实例化一个线程对象th1,该线程开始执行
thread th2(thread2);
LOG(INFO)<<"********"<
th1.join();
LOG(INFO)<<"********"<
th2.join();
LOG(WARNING)<<"main...";
return 0;}//结果分析:此时就可以正常执行子线程了,同时注意最后一个输出,说明了main是等待子线程结束后才继续执行的.//需要注意的是,线程对象执行了join后就不再joinable(判断线程是否可以加入等待)了.所以只能join一次.//joinable:检查线程是否可以被join.检查当前的线程对象表示了一个活动的执行过程,有默认构造函数创建的线程是不能被join的.//另外,如果某个线程已经执行完,但是没有被join的话,该线程依然被认为是一个活动的线程,因此也是可以被join的.

2.2 编译结果

在这里插入图片描述

3. thread::detach( )

3.1 thread.cpp

//解决方法:thread::detach()//将当前线程对象所代表的执行实例与该线程对象分离,使得线程的执行可以单独进行.一旦线程执行完毕,它所分配的资源将会被释放.//detach是用来分离线程,这样线程可以独立执行,不过这样由于没有thread对象指向该线程而失去了对它的控制.//当对象析构时,线程会继续在后台执行,但是当主程序退出时并不能保证线程执行完.//如果没有良好的控制机制或者这种后台线程比较重要,最好不用detach而使用join.#include 
   
    #include 
    
     #include 
     
      using namespace std;void thread1(){

      
   for(int i = 0; i < 10; ++i)
{
   cout<<"thread1..."<
}}void thread2(){
   for(int i = 0; i < 10; ++i)
{
   cout<<"thread2..."<
}}int main(int argc, char* argv[]){
   google::InitGoogleLogging(argv[0]);
FLAGS_logtostderr = 1;
FLAGS_colorlogtostderr = 1;
thread th1(thread1);
thread th2(thread2);
th1.detach();
th2.detach();
LOG(ERROR)<<"main...";
return 0;}//结果分析: 子线程与主程序分开执行,当对象析构时,子线程会继续在后台执行.

3.2 编译结果

在这里插入图片描述

4. mutex

mutex是防止不同的线程同时操作同一个共享数据.

4.1 mutex_test.cpp

//头文件mutex是用来保证线程同步的,防止不同的线程同时操作同一个共享数据.//#include:该头文件主要声明了与互斥量相关的类,//包括std::mutex系列类,std::lock_guard,std::unique_lock#include 
   
    #include 
    
     #include 
     
      #include 
      
       using namespace std;mutex m;int cnt = 10;void thread1(){

       
   while(cnt > 5)
{
   m.lock();
if(cnt > 0)
{
   --cnt;
cout< <
}
m.unlock();
}}void thread2(){
   while(cnt > 0)
{
   m.lock();
if(cnt > 0)
{
   cnt -= 10;
cout< <
}
m.unlock();
}}int main(int argc, char* argv[]){
   google::InitGoogleLogging(argv[0]);
FLAGS_logtostderr = 1;
FLAGS_colorlogtostderr = 1;
thread th1(thread1);
thread th2(thread2);
th1.join();
th2.join();
LOG(WARNING)<<"main...";
return 0;}

4.2 编译结果

在这里插入图片描述

  • 结果分析:mutex是不安全的,如果当一个线程在解锁之前就异常退出了,那么其他被阻塞的线程就无法进行下去.

5. std::lock_guard

5.1 lock_guard.cpp

使用lock_guard则相对安全,它是基于作用域的,能够自解锁.

//使用lock_guard则相对安全,它是基于作用域的,能够自解锁,当该对象创建时,它会像m.lock()一样获得互斥锁//当生命周期结束时,它会自动析构(unlock),不会因为某个线程异常退出而影响其他线程.#include 
   
    #include 
    
     #include 
     
      #include 
      
       using namespace std;mutex m;int cnt = 10;void thread1(){

       
   while(cnt > 5)
{
   lock_guard  lock(m);
if(cnt > 0)
{
   --cnt;
cout< <
}
}}void thread2(){
   while(cnt > 0)
{
   lock_guard  lock(m);
if(cnt > 0)
{
   cnt -= 2;
cout< <
}
}}int main(int argc, char* argv[]){
   google::InitGoogleLogging(argv[0]);
FLAGS_logtostderr = 1;
FLAGS_colorlogtostderr = 1;
thread th1(thread1);
thread th2(thread2);
th1.join();
th2.join();
LOG(WARNING)<<"main...";
return 0;}

5.2 编译结果

在这里插入图片描述

转载地址:https://blog.csdn.net/weixin_46181372/article/details/115533047 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Scan Context 学习记录
下一篇:PCL_viewer指令

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.173.107.156]2022年09月28日 07时15分22秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

最新文章

主键索引和唯一索引的区别 2019-07-18 08:07:38
ebay 付款时间 跟中国时间的关系 2019-07-18 08:07:38
php 代码规范 2019-07-18 08:07:37
PayPal提现操作流程 2019-07-18 08:07:37
测试驱动开发 2019-07-18 08:07:36
什么是主题酒店? 2019-07-18 08:07:36
软件开发原则之依赖倒置原则 2019-07-18 08:07:35
html5 特性介绍 2019-07-18 08:07:35
国际日期书写标准格式 2019-07-18 08:07:34
paypal账户提现收费标准 2019-07-18 08:07:34
fpm简介 2019-07-18 08:07:33
网页字体 2019-07-18 08:07:33
restfull架构 2019-07-18 08:07:32
lnmp下php安装ldap扩展 2019-07-18 08:07:32
ldap objectclass and attribute 2019-07-18 08:07:31
Linux下安装openldap 2019-07-18 08:07:31
PHP遍历文件夹及子文件夹所有文件 2019-07-18 08:07:30
virtualbox nat网络模式下 实现宿主机访问虚拟机 2019-07-18 08:07:30
Rsync 最快速删除海量文件的方法 2019-07-18 08:07:29
MySQL Connections to sleep 2019-07-18 08:07:29