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. jquery实现自定义弹出框

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. vs2017调用目标发生了异常

    解决办法: 1. 在开始菜单,找到“Visual Studio Tools”文件夹中的“VS 2017的开发人员命令提示符 ” 运行. 2. 输入:devenv /Safemode 3. 会以安全模式 ...

  3. python代码docstring生成文档之sphinx

    在使用python中,我们一般在模块,类,函数下使用docstring添加字符串说明性文档,使开发人员更好的可以看懂此代码是做什么用的.然而写了那么多的注释,我们想要一篇文档怎么办,第一种办法不可能将 ...

  4. C#子线程执行完后通知主线程

    其实这个比较简单,子线程怎么通知主线程,就是让子线程做完了自己的事儿就去干主线程的转回去干主线程的事儿. 那么怎么让子线程去做主线程的事儿呢,我们只需要把主线程的方法传递给子线程就行了,那么传递方法就 ...

  5. jmeter 多压力机并发测试过程

    要实现多台压力机并发,就必须有多台服务器上安装了jmeter程序包,首先把一台服务器作为主压力机,测试脚本放到这台机器上,主压力机与从压力机在同一局域网中,服务器之间可以ping通 第一步:在linu ...

  6. Android repo 学习参考

    /*************************************************************************** * Android repo 学习参考 * 说 ...

  7. Linux Shell 判断块设备节点是否存在

    /************************************************************************* * Linux Shell 判断块设备节点是否存在 ...

  8. HDU3579Hello Kiki(中国剩余定理)(不互质的情况)

    One day I was shopping in the supermarket. There was a cashier counting coins seriously when a littl ...

  9. 影响Cache的几个HTTP头信息【转载http://hi.baidu.com/feilala_fly/item/f79eca08fbf389026c9048a7】

    Http的Cache机制总共有4个组成部分: Cache-Control.Last-Modified(If-Modified-Since).Etag(If-None-Match) .Expires 服 ...

  10. Cloudera运维

    1. 增加一个节点 1. 拷贝cm的jar包到该节点 2. 设置hostname(hostnamectl set-hostname XXX),然后修改hosts文件 3. 所有的节点添加该hostna ...