2019独角兽企业重金招聘Python工程师标准>>>

几种线程的方式

##创建线程

通过函数指针来创建一个线程

#include <iostream>
#include <thread>
void thread_function(){for (int i = 0; i < 10000; i++) {std::cout<<"thread function Executing"<<std::endl;}
}int main(int argc, char const* argv[])
{std::thread threadobj(thread_function);for (int i = 0; i < 10000; i++) {std::cout<<"Display From MainTHread"<<std::endl;}threadobj.join();std::cout<<"Exit of Main function"<<std::endl;return 0;
}

使用函数对象创建一个线程

#include <iostream>
#include <thread>
class DisplayThread{public:void operator()(){for (int i = 0; i < 10000; i++) {std::cout<<"Display Thread executing"<<std::endl;}}
};int main(int argc, char const* argv[])
{std::thread threadobj((DisplayThread()));for (int i = 0; i < 10000; i++) {std::cout<<"Display from main thread"<<std::endl;}std::cout<<"Waiting for thread to complete"<<std::endl;threadobj.join();std::cout<<"Exiting from main thread"<<std::endl;return 0;
}

使用 匿名函数来创建线程


#include <iostream>
#include <thread>
int main(){int x=9;std::thread threadObj([]{for (int i=0;i<10000;i++)std::cout<<"Display thread executeing"<<std::endl;});for (int i = 0; i < 10000; i++) {std::cout<<"Display from main thread"<<std::endl;}threadObj.join();std::cout<<"Exiting from Main Thread"<<std::endl;return 0;
}

不同线程之间的区别

第一个线程都会有一个ID 成员函数指定关联线程对象的ID std::thread::get_id() 给出当前函数的标识符 std::this_thread::get_id()

如果std::thread 对象没有任何关联的线程,get_id会返回一个默认的构造的std::thread::id对象 std::thread::id是一个对象,可以比较和输出 示例代码

#include <iostream>
#include <thread>void thread_function(){std::cout<<"Inside Thread :: ID="<<std::this_thread::get_id()<<std::endl;}
int main(int argc, char const* argv[])
{std::thread threadObj1(thread_function);std::thread threadObj2(thread_function);if(threadObj1.get_id()!=threadObj2.get_id())std::cout<<"BOth threads have diferent IDs"<<std::endl;std::cout<<"From Main thread :: id of thread 1="<<threadObj1.get_id()<<std::endl;std::cout<<"From Main thread :: id of thread 2="<<threadObj2.get_id()<<std::endl;return 0;
}

加入和分离线程

joining 线程 一旦线程开始启动之后,其他的线程可以等待这个新的线程完成。等到其他的线程调用 join()函数

std::thread th(funPtr); th.join() 我们来看一个示例 假设主线程已经启动了10个线程,直到所有的线程结束之后再退出。

#include <iostream>
#include <thread>
#include <algorithm>
#include <vector>
class WorkerThread {public:void operator()(){std::cout<<"Worker Thread "<<std::this_thread::get_id()<<" is Executing "<<std::endl;}
};int main(int argc, char const* argv[])
{std::vector<std::thread> threadList;for (int i = 0; i < 10; i++) {threadList.push_back(std::thread(WorkerThread()));}std::cout<<"等待所有的工作线程完成"<<std::endl;std::for_each(threadList.begin(),threadList.end(),std::mem_fn(&std::thread::join));std::cout<<"退出主线程"<<std::endl;return 0;
}

分离线程 分享之后的线程也称做后台进程。分离一个线程我们需要调用 std::detach()函数

std::thread th(funcPtr); th.detach();

一旦分享之后并不会再跟主线程关联 所以我们需要小心的使用detach()和join() 避免出现不可预知的问题

#include <iostream>
#include <thread>
#include <algorithm>
#include <vector>
class WorkerThread {public:void operator()(){std::cout<<"Worker Thread "<<std::this_thread::get_id()<<" is Executing "<<std::endl;}
};int main(int argc, char const* argv[])
{std::thread threadObj((WorkerThread()));if ( threadObj.joinable() ){std::cout<<"Detaching Thread "<<std::endl;threadObj.detach();}if ( threadObj.joinable() ){std::cout<<"Detaching Thread "<<std::endl;threadObj.detach();}std::thread threadObj2((WorkerThread()));if ( threadObj2.joinable() ){std::cout<<"Detaching Thread "<<std::endl;threadObj2.detach();}if ( threadObj2.joinable() ){std::cout<<"Detaching Thread "<<std::endl;threadObj2.detach();}return 0;
}

#include <iostream>
#include <thread>
class ThreadRAII
{std::thread & m_thread;public:ThreadRAII(std::thread  & threadObj) : m_thread(threadObj){}~ThreadRAII(){// 判断线程是否可被分离if(m_thread.joinable()){m_thread.detach();}}
};
void thread_function()
{for(int i = 0; i < 10000; i++)std::cout<<"thread_function Executing"<<std::endl;
}int main()
{std::thread threadObj(thread_function);// 如果我们注释这行程序并会崩溃ThreadRAII wrapperObj(threadObj);return 0;
}

传递参数给线程

其中chrono原是boost的一个时间处理的库,现已成为c++ 11的标准了。

#include <iostream>
#include <thread>
void newThreadCallback(int *p){std::cout<<"Inside Thread :"":p="<<p<<std::endl;std::chrono::milliseconds dura(10000);std::this_thread::sleep_for(dura);*p=19;
}
void startNewThtread(){int i=10;std::cout<<"Inside Main Thread:"":i= "<<i<<std::endl;std::thread t(newThreadCallback,&i);t.detach();std::cout<<"Inside Main Thread : "": i="<<i<<std::endl;
}
int main(int argc, char const* argv[])
{startNewThtread();std::chrono::milliseconds dura(2000);std::this_thread::sleep_for(dura);return 0;
}

有的时候我们需要注意的是,当你将一个对象的指针传递给一个线程时,而这个对象可能在传递的线程之外被删除,那么该线程再次访问的时候会出现段错误。比如说下面的这段程序

#include <iostream>
#include <thread>
void newThreadCallback(int* p){std::cout<<"inside Thread :"":p="<<p<<std::endl;std::chrono::milliseconds dura(1000);std::this_thread::sleep_for(dura);*p=19;
}
void startNewThread(){int *p=new int();*p=10;std::cout<<"Inside Main Thread:"":*p="<<*p<<std::endl;std::thread t(newThreadCallback,p);t.detach();delete p;p=NULL;
}
int main(int argc, char const* argv[])
{startNewThread();std::chrono::milliseconds dura(2000);std::this_thread::sleep_for(dura);return 0;
}

给线程传递一个形参

有的时候我们需要在程序中将某一些对象添加到某一线程的堆栈当中,一旦在线程里面更新并可以同步到主线程当中。

#include <iostream>
#include <thread>
void threadCallback(int const & x){int &y=const_cast<int &>(x);y++;std::cout<<"Inside Thread x="<<x<<std::endl;
}
int main(int argc, char const* argv[])
{int x=9;std::cout<<"In main thread :before thread start x ="<<x<<std::endl;std::thread threadObj(threadCallback,x);threadObj.join();std::cout<<"In main thread : after thread joins x="<<x<<std::endl;return 0;
}

输出 In main thread :before thread start x =9 Inside Thread x=10 In main thread : after thread joins x=9

上面的程序看似threadCallback接收一个形参,在传递给threadCallback的时候线程会复制一个临时的值,更改该值并不影响外面的变量

倘若我们需要实际在线程里面改变外部的值,需要通过std::ref()的方式来传递值。

#include <iostream>
#include <thread>
void threadCallback(int const & x){int &y=const_cast<int &>(x);y++;std::cout<<"Inside thread x ="<<x<<std::endl;
}
int main(int argc, char const* argv[])
{int x=9;std::cout<<"in main thread:before thread start x="<<x<<std::endl;std::thread threadObj(threadCallback,std::ref(x));threadObj.join();std::cout<<"In Main Thread :After thread joins x ="<<x<<std::endl;return 0;
}

输出: in main thread:before thread start x=9 Inside thread x =10 In Main Thread :After thread joins x =10

实现一个线程类的功能

在创建的thread的时候其中第一项传递的是成员函数做为线程的回调函数,而第二项传递的是操作的对象。

#include <iostream>
#include <thread>
class DummyClass {
public:DummyClass(){}DummyClass(const DummyClass & obj){}void sampleMemberFunction(int x){std::cout<<"Inside sampleMemberFunction "<<x<<std::endl;}
};
int main() {DummyClass dummyObj;int x = 10;std::thread threadObj(&DummyClass::sampleMemberFunction,&dummyObj, x);threadObj.join();return 0;
}

转载于:https://my.oschina.net/u/215677/blog/708033

c++ 11 多线程处理(1)相关推荐

  1. java类与对象实验报告心得体会_java上机实验心得体会报告(大全五篇)

    北京联合大学信息学院 "面向对象程序设计"课程上机实验报告 题目: JAVA上机实验心得体会 姓名(学号): 专业:计算机科学与技术 编制时间: 2012年12月19日 版本: 1 ...

  2. java实验2总结心得,java实验的心得体会

    java实验的心得体会 java实验心得体会篇一:java实验总结 1. 设计一个Person类,包含:姓名,年龄,性别.要求:该类至多只能创建一男.一女两个对象! 2. 设计一个测试类Test,创建 ...

  3. java上机实验心得_java上机实验心得体会报告

    java上机实验心得体会报告 北京联合大学 信息学院 "面向对象程序设计"课 程上机实验报告 题 目: JAVA 上机实验心得体会 姓名(学号): 专 业: 计算机科学与技术 编 ...

  4. 掌握11项技能,你就是优秀的前端开发工程师

    导读: 你也许会觉得前端开发是一个很简单的工作,对呀,你就是刚刚从网页设计转型过来的.但当你深入其中时,一定会发现好像前端开发不是那么简单,光网站性能优化.响应式.框架就让你焦头烂额, 确实,做前端开 ...

  5. 初学Web前端开发,你需要掌握的11项技能

    你也许会觉得Web前端开发是一个很简单的工作,但当你深入其中时,一定会发现好像Web前端开发不是那么简单,光网站性能优化.响应式.框架就让你焦头烂额.确实,做前端开发就是先易后难,想成为一个优秀的We ...

  6. 按钮开始多线程_微软MR技术专家分享:AR/VR多线程处理的八年经验与技巧

    查看引用/信息源请点击:映维网 关于多线程的经验分享 (映维网 2020年11月17日)多线程(Multithreading)是指从软件或者硬件实现多个线程并发执行的技术.具有多线程能力的计算机因有硬 ...

  7. (一)C++11 原生标准多线程:认识多线程

    之所以称之为C++11原生标准多线程,因为在C++中C++11版本才加入的多线程.所谓原生也就是C++语言自带的,区别于其他库实现,比如POSIX,Boost,winAPI,QT[藐视很少有人提到QT ...

  8. ROS单线程与多线程处理

    ROS wiki:http://wiki.ros.org/ ROS API:https://docs.ros.org/en/api/roscpp/html/index.html ROS单线程与多线程处 ...

  9. Spring事务内多线程处理-解决方案

    首先,Spring Ioc 依赖注入的就是单例对象,我们在使用的时候如果有多个相同处理且不怎么耗时的情况下一般会采用for循环直接执行,这样的情况下即使有事务管理也不会影响业务执行下去:但是,大多数的 ...

最新文章

  1. 【mysql错误】用as别名 做where条件,报未知的列 1054 - Unknown column 'name111' in 'field list'...
  2. random函数用法_Python函数式编程:从入门到走火入魔
  3. MODIS(TerraAqua)陆地标准产品
  4. 自定义ListView背景(解决了拖动变黑的效果)
  5. 对话腾讯云汽车业务副总经理李博:构建出行大版图,腾讯云迈向新征程
  6. Python和单元测试那些事儿
  7. java读取clob字段的几种方法(转)
  8. 帝国cms模板嵌入php,帝国cms模板中php调用信息的例子
  9. 深度学习2.0-9.tensorflow的高阶操作之填充与复制
  10. Python argv小结
  11. STM32学习笔记(三 时钟系统 1 时钟系统精讲)
  12. 中文核心期刊投稿指南
  13. java 睡眠1s_Java sleep():线程睡眠
  14. 开启memcached日志
  15. 范蠡传(司马迁-史记)
  16. php.c drcom,成功 将校园客户端drcom搞进openwrt
  17. 解决Orcale登录界面乱码问题(linux)
  18. WPF 方块按钮 仿照360
  19. ubuntu14.04LTS安装steam
  20. 股票每日复盘都应该做什么,需要从哪些方面复盘?

热门文章

  1. 【分享】在线解析微信h5网页标签跳转到手机默认浏览器的实现方式
  2. MySQL数据库--连接
  3. Java中的泛型 --- Java 编程思想
  4. bootstrap-table页码ALL显示为NAN
  5. 面向对象的软件测试技术
  6. ansible学习笔记
  7. python staticmethod and classmethod方法
  8. 分支-03. 三天打鱼两天晒网(Switch…case)
  9. Oracle VM VirtualBox 虚拟机中ubuntu里,鼠标滚轮不能使用
  10. MSP430学习笔记5-利用蜂鸣器演奏音乐