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. Spark- Spark内核架构原理和Spark架构深度剖析

    Spark内核架构原理 1.Driver 选spark节点之一,提交我们编写的spark程序,开启一个Driver进程,执行我们的Application应用程序,也就是我们自己编写的代码.Driver ...

  2. python的字符串操作函数之一览

    s.strip(chars) s.find(x,start,end) s.index(x.start,end)#见上: s.format()#见上: s.partition(x)#见上: s.repl ...

  3. JavaScript秘密

    对象 对象使用和属性 JavaScript 中所有变量都可以当作对象使用,除了两个例外 null 和 undefined. false.toString(); // 'false' [1, 2, 3] ...

  4. Linux课程---2、Linux下最常用命令(查看帮助命令)

    Linux课程---2.Linux下最常用命令(查看帮助命令) 一.总结 一句话总结: man 1.显示文件? ls:ls带其它参数详情可以man ls man ls:比如 ls -a显示隐藏文件,l ...

  5. django1.8.3搭建博客——1

    系统:elementary os python 2.7.6 django 1.8.3 1.安装django 先安装pip   sudo apt-get install python3-pip 安装dj ...

  6. JS中的prototype、__proto__与constructor属性

    作为一名前端工程师,必须搞懂JS中的prototype.__proto__与constructor属性,相信很多初学者对这些属性存在许多困惑,容易把它们混淆,本文旨在帮助大家理清它们之间的关系并彻底搞 ...

  7. js 定义hash类

    // JavaScript Documentfunction HashTable(){    this._hash={};    this._count=0;            /**    *添 ...

  8. MFC实现普通DLL

    库有两种:动态链接库和静态链接库. 一,使用动态链接库: 通过项目——属性——配置属性——常规——项目默认值——配置类型下,选择动态库(.dll)选项 这样会生成.lib和.dll两种文件. 只是该. ...

  9. C++ vector容器删除操作

    1.vector::pop_back() 删除vector的最后一个元素,vector的大小减一,删了的元素被销毁. 2.vector::erase() iterator erase (iterato ...

  10. 使用 Anthem.NET 的经验小结

    1. 不依靠 Panel 来做省事的区域性 Ajax. 2. 控件不要图偷懒设置 AutoUpdateAfterCallBack = true. 而是每次需要更新的时候指定 UpdateAfterCa ...