Thread线程框架

线程定义:
线程可以理解为一个特立独行的函数。其存在的意义,就是并行,避免了主线程的阻塞。


----------------------------thread与函数----------------------------------

线程启动

  C++线程的启动, 只需要#include <thread>即可。 线程对象的创建, 意味着线程的开始。

1)同步

#include <iostream>
#include <thread>
#include <unistd.h> using namespace std; void func()
{
cout<<"thread id:"<<this_thread::get_id()<<endl;
cout<<"do some work"<<endl;
sleep();
}
int main()
{
cout<<"maint thread id:"<<this_thread::get_id()<<endl;
thread t(func);
t.join();
return ;
}

  t.join 和 t.detach 标志着, 线程对象和线程的关系。 t.join 表示, 线程与线程对象的同步关系。 而 t.detach 表示, 线程与线程对象的异步关系。 在线程生成后,必须指定join或者detach状态来。

  detach 后的线程,不能再 join,是否可以 join 可以通过 joinable 来判断。 

2)异步

#include <iostream>
#include <memory> using namespace std; void func()
{
cout<<"thread id:"<<this_thread::get_id()<<endl;
int i = ;
while(i++<)
{
cout<<"assist thread running times:"<<i<<endl;
sleep();
}
cout<<"----end assist thread work!------"<<endl;
} int main()
{
cout<<"maint thread id:"<<this_thread::get_id()<<endl;
thread t(func);
// t.join(); //!同步
t.detach(); //!异步 int i =;
while(i++<)
{
cout<<"main thread running times:"<<i<<endl;
sleep();
}
cout<<"-----main thread finished!-----"<<endl;
}

  在次线程detach的状态下,要保证主线程的上声明周期要比次线程声明周期长,否则此线线程将中断退出。

传参方式

  线程有自己独立的栈。可供享受全局的变量。在线程启动的时候可以传入启动的参数。

#include <iostream>
#include <thread>
using namespace std; void func(int n, string s)
{
for(int i=;i <n ;i++)
{
cout<<s<<endl;
}
}
int main()
{
thread t(func,,"china");
t.join();
return ;
}

  除了传入参数,共享全局以外,还可以使用std::ref辅助传入本地变量的引用。thread认为不加std::ref包装的变量都是以拷贝的方式传入线程中去的。

#include <iostream>
#include <thread>
using namespace std; void func(int &n, string &s)
{
for(int i=;i <n ;i++)
{
cout<<s<<endl;
}
n = ;
s = "america";
} int main()
{
int n = ;
string s = "china";
// thread t(func,n, s); //!编译不过,thread无法区分传入的参数
thread t(func,ref(n), ref(s)); //!正确的传引用的姿势,应该采用std::ref来对变量包装
t.join();
return ;

 

----------------------------thread与类成员函数-----------------------------------

  以上都是通过线程来包装普通的函数。类的成员函数该如何引入线程呢?如下:

1)类外使用线程(推荐):

#include <iostream>
#include <thread> using namespace std; class ThreadTest
{
public:
ThreadTest()
{
cout<<"ThreadTest():"<<this<<endl;
}
void func()
{
int n = ;
cout<<"void func(int n):"<<this<<endl;
while(n++<)
{
cout<<"thread in class runtime:"<<n<<endl;
}
}
~ThreadTest() = default;
}; int main()
{
ThreadTest test;
thread t(&ThreadTest::func,test);
t.join();
cout<<"Pls observe the difference between the two printed addresses!"<<endl;return ;
}

  这个函数执行起来显然没什么错误,但是有一个问题:我们构造时对象的内存地址居然与多线程中执行函数地址不一样,要记住这可是该对象的成员函数啊?我们前面已经提到过,不使用std::ref传入线程的变量默认都是以拷贝的方式传入的。两次地址不一样的原因就是如此!要想将该对象的成员函数加入线程,我们应该使用std::ref或者直接传入对象的指针。

#include <iostream>
#include <thread> using namespace std; class ThreadTest
{
public:
ThreadTest()
{
cout<<"ThreadTest():"<<this<<endl;
}
void func()
{
int n = ;
cout<<"void func(int n):"<<this<<endl;
while(n++<)
{
cout<<"thread in class runtime:"<<n<<endl;
}
}
~ThreadTest() = default;
}; int main()
{
ThreadTest test;
// thread t(&ThreadTest::func,test); //!对象拷贝
  thread t(&ThreadTest::func,std::ref(test));       //!传入引用
// thread t(&ThreadTest::func,&test); //!传入指针;
t.join();
cout<<"Please observe the difference between the two printed addresses!"<<endl;return ;
}

2)类内使用线程:

#include <iostream>
#include <thread>
using namespace std; class ThreadInClass
{
public:
ThreadInClass(){cout<<"ThreadInClass():"<<this<<endl;}
~ThreadInClass() = default;
void runThread()
{
thread t(&ThreadInClass::func,this);
t.join();
// t.detach();//使用detach,同样也要保证runThread的生存周期比t要长。
}
void func()
{
int n = ;
cout<<"void func(int n):"<<this<<endl;
while(n++<){
cout<<"thread in class runtime:"<<n<<endl;
}
}
}; int main()
{
ThreadInClass tic;
tic.runThread();
}

 

C++多线程框架的更多相关文章

  1. C++多线程框架-----Mutex互斥和Sem信号量

           互斥和信号量是多线程编程的两个基础,其原理就不详细说了,大家去看看操作系统的书或者网上查查吧. 对于互斥的实现,无论什么操作系统都离不开三个步骤 1.初始化互斥锁 2.锁操作 3.解锁操 ...

  2. Java程序员必备知识-多线程框架Executor详解

    为什么引入Executor线程池框架 new Thread()的缺点 每次new Thread()耗费性能 调用new Thread()创建的线程缺乏管理,被称为野线程,而且可以无限制创建,之间相互竞 ...

  3. Executor多线程框架使用

    在我们的JDK1.5的时候JAVA推出一款为了更加方便开发的多线程应用而封装的框架(Executor),相比传统的Thread类,Executor更加的方便,性能好,更易于管理,而且支持线程池.一般在 ...

  4. Java基础之多线程框架

    一.进程与线程的区别 1.定义: 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位. 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比 ...

  5. windows多线程框架

    #include <iostream> #include <windows.h> using namespace std; HANDLE hMutex; //public : ...

  6. Java多线程框架Executor详解

       原文链接  http://www.imooc.com/article/14377 为什么引入Executor线程池框架new Thread()的缺点 每次new Thread()耗费性能调用ne ...

  7. Java内置多线程框架Executor

    JDK1.5之后,增加了一个Executor让我们能更好的使用多线程. 它位于java.util.concurrent包下 因为是JDK内置类库,我们不需要导入任何第三方jar包. 代码实例: imp ...

  8. java.util.concurrent 多线程框架

    http://daoger.iteye.com/blog/142485 JDK5中的一个亮点就是将Doug Lea的并发库引入到Java标准库中.Doug Lea确实是一个牛人,能教书,能出书,能编码 ...

  9. java多线程框架

    JDK5中的一个亮点就是将Doug Lea的并发库引入到Java标准库中.Doug Lea确实是一个牛人,能教书,能出书,能编码,不过这在国外还是比较普遍的,而国内的教授们就相差太远了. 一般的服务器 ...

随机推荐

  1. CDH- 测试mr

    cdh的mr样例算法的jar包在 [zc.lee@ip---- hadoop-0.20-mapreduce]$ pwd /opt/cloudera/parcels/CDH--.cdh5./lib/ha ...

  2. DBGrid和DBGridEH

    二.应用实例 Enlib3.0组件包安装成功后 A.定制标题行 1.制作复杂标题行 标题行可设为2行以上高度,并可以为多列创建一个共同的父标题行.为实现这个效果,需在各个列标题属性中以“|”分隔父标题 ...

  3. windows下安装配置nginx

    下载nginx-1.0.11.zip, 解压到到nginx目录下 D:\nginx\conf 修改conf下的nginx.conf文件, 默认是80端口,若该端口被占则可以修改 listen 8073 ...

  4. iis_rewrite3突然无法使用(因为它过期啦)

    转自http://www.b1y.cn/post/216.html ISAPI_Rewrite3完全版会有45天的试用期,过期了需要99美元进行够买,网上有很多破解版的,方法如下: 1.先从官网下一个 ...

  5. CCSpriteBatchNode CCSpriteFrameCache

    3.27 精灵集合类(CCSpriteBatchNode) //以纹理来创建一个精灵集合对象 static CCSpriteBatchNode* createWithTexture(CCTexture ...

  6. 【遍历二叉树】08判断两个二叉树是否相同【Same Tree】

    迭代版本用的是二叉树的DFS,中的root->right->left +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ...

  7. linux 故障:df -h统计磁盘空间占用太多,但又du -h找不到大的文件

    用lsof / | grep -i delete 从根目录定位打开的被删除的文件 如果定位到某文件占用空间很大 主要是因为我们在删除这个日志文件的时候是用rm -rf *.log这样的命令删除的,删除 ...

  8. CRtmpServer

    1.  前言 crtmpserver是一个由C++语言编写的开源的RTMP流媒体服务器,官方网站是www.rtmpd.com 2.   CRtmpServer编译   2.1.  Win7+Vs201 ...

  9. ACM学习历程—FZU2195 检查站点(树形DP || 贪心)

    Description 在山上一共有N个站点需要检查,检查员从山顶出发去各个站点进行检查,各个站点间有且仅有一条通路,检查员下山前往站点时比较轻松,而上山时却需要额外的时间,问最后检查员检查完所有站点 ...

  10. BZOJ2733:[HNOI2012]永无乡

    浅谈线段树合并:https://www.cnblogs.com/AKMer/p/10251001.html 题目传送门:https://lydsy.com/JudgeOnline/problem.ph ...