一、用一个初始函数创建一个线程

直接看代码:注意c++在运行一个可执行程序的时候(创建了一个进程),会自动的创建一个主线程,这个主线程和进程同生共死,主线程结束,进程也就结束了。

 #include "pch.h"
#include <iostream>
#include<thread>
void print1()
{
cout << "print1_1线程执行" << endl;
cout << "print1_2线程执行" << endl;
cout << "print1_3线程执行" << endl;
}
using namespace std;
int main()
{
thread mythread1(print1);
mythread1.join();
//mythread1.detach();
cout << "主线程执行" << endl;
return ;
}

thread mythread1(print1)创建一个线程mythread1,print1()是该线程的初始函数(执行函数)。

mythread1.join();阻塞主线程,等待mythread1这个线程执行完毕在继续执行,推荐这种做法。

mythread1.detach();分离,使主线程和线程mythread1分离,主线程可以先执行结束,如果主线程执行完了,子线程会在c++后台运行,一旦使用detach(),与这个子线程关联的对象会失去对这个主线程的关联,此时这个子线程会驻留在c++后台运行,当主线程执行完毕结束,子线程会移交给c++运行时库管理,这个运行时库会清理与这个线程相关的资源(守护线程),detach()会是子线程失去进程的控制,所以建议不要使用detach(),建议使用jion()。

return 0;表示主线程执行完毕,表明进程即将退出。

二、用类对象创建一个线程

直接看代码:

 #include "pch.h"
#include <iostream>
#include<thread>
class T
{
public:
/*情况一:
int &it;//一个进程中的所有线程共享同一块内存(内存共享),在线程中使用引用其实是不安全的
T(int &m_it) :it(m_it)
{
cout << "构造函数被执行" << endl;
}
*/
//不能用引用,应该像下面这样用
int it;
T(int m_it) :it(m_it)
{
cout << "构造函数被执行" << endl;
}
T(const T &t) :it(t.it) {
cout << "拷贝构造函数被执行" << endl;
}
~T()
{
cout << "析构函数被执行" << endl;
}
void operator()()
{
cout << "it值:" << it << endl;
}
};
int main()
{
int itm = ;
T t(itm);//调用了构造函数
thread mythread2(t);
mythread2.join();
//mythread2.detach();
cout << "主线程执行" << endl;
return ;
}

thread mythread2(t);调用了拷贝构造函数

mythread2.detach();情况一的时候,这里绝对不能用detach(),因为类成员变量是一个引用,这里的itm等主线程执行完毕之后内存会回收,所以子线程打印的变量无效,这是一个重大的bug。一定要注意,最安全的做法就是直接使用值传递,生成一个副本,这样使用detach()就不会有错。

这里还有一个疑问?为什么使用detach(),主线程执行结束之后,用t这个局部对象没有问题,t按理说会被系统回收之后就有问题了呀?
答:虽然t这个对象不在了(肯定会被回收),但是创建子线程的时候,这个对象t是被拷贝到子线程中去了的,所以用detach()而且主线程执行完毕后,子线程还是会继续执行,这是没有问题的.t被销毁,但是被复制到线程中去的对象依然存在。

三、用lambda表达式创建一个线程

直接看代码:

 #include <iostream>
#include<thread>
using namespace std;
int main()
{
//用lambda表达式创建一个线程
auto mylamthread = [] {//这是一个lambda表达式
cout << "我的线程开始执行了" << endl;
//......
cout << "我的线程执行结束了" << endl;
};
thread mythread3(mylamthread);
mythread3.join();
cout << "主线程执行结束" << endl;
return ;//表示主线程执行结束,表明进程结束
}

四、认识一个函数

joinable(),这个函数用来判断是否还可以使用join()和detach(),如果已经使用了join()或者detach(),则不能再使用detach()或者join()函数了,会返回一个布尔true,反之,返回一个false.

c++11线程创建的三种方法的更多相关文章

  1. 线程创建的三种方法:继承Thread类,实现Runnable接口,实现Callable接口

    线程创建 三种创建方式 1. 继承Thread类 自定义线程类继承Thread类 重写run()方法,编写线程执行体 创建线程对象,调用start()方法启动线程 线程不一定执行,CPU按排调度 pa ...

  2. java多线程二之线程同步的三种方法

          java多线程的难点是在:处理多个线程同步与并发运行时线程间的通信问题.java在处理线程同步时,常用方法有: 1.synchronized关键字. 2.Lock显示加锁. 3.信号量Se ...

  3. JAVA之线程同步的三种方法

    最近接触到一个图片加载的项目,其中有声明到的线程池等资源需要在系统中线程共享,所以就去研究了一下线程同步的知识,总结了三种常用的线程同步的方法,特来与大家分享一下.这三种方法分别是:synchroni ...

  4. JavaScript高级程序设计--对象创建的三种方法

    创建对象的三种方法: 1.工厂模式 工厂模式是软件工程领域广为人知的设计模式,这种模式抽象了创建具体对象的过程.下面是使用工厂函数创建对象的的一个例子. 2.构造函数: 从上面的例子中,我们看到构造函 ...

  5. Java中实现线程同步的三种方法

    实现同步的三种方法 多线程共享数据时,会发生线程不安全的情况,多线程共享数据必须同步. 实现同步的三种方法: 使用同步代码块 使用同步方法 使用互斥锁ReetrantLock(更灵活的代码控制) 代码 ...

  6. AJPFX总结线程创建的两种方法

    创建线程的第一种方式:继承Thread ,由子类复写run方法.步骤:1,定义类继承Thread类:2,目的是复写run方法,将要让线程运行的代码都存储到run方法中:3,通过创建Thread类的子类 ...

  7. java_线程创建的两种方法

    线程创建的方法有两种: 一 继承Thread类: public class ThreadTest { public static void main(String[] args) { //4)在mai ...

  8. java_线程创建的三种方式及区别

    java中关于线程的创建有三种: (1)通过继承Thread类创建线程. (2)通过实现Runnable接口创建线程. (3)通过Callable 和 Future 接口创建线程. * * * * * ...

  9. 【转】 Linux 线程同步的三种方法

    线程的最大特点是资源的共享性,但资源共享中的同步问题是多线程编程的难点.linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量和信号量. 一.互斥锁(mutex) 通过锁机制实现线程间的 ...

随机推荐

  1. C#基础拾遗系列之二:使用ILSpy探索C#7.0新增功能点

    C#基础拾遗系列之二:使用ILSpy探索C#7.0新增功能点   第一部分: C#是一种通用的,类型安全的,面向对象的编程语言.有如下特点: (1)面向对象:c# 是面向对象的范例的一个丰富实现, 它 ...

  2. Java 之初(1)

    省赛结束之后有相当长一段空闲时间,于是就想先提前自学一点Java语言的知识,在这里纪录一下学习过程,希望能给自学Java的同学提供一点小帮助!(当然,也能方便我以后的复习用^_^) 在学习过程中有什么 ...

  3. springboot 使用webflux响应式开发教程(一)

    什么是webFlux 左侧是传统的基于Servlet的Spring Web MVC框架,右侧是5.0版本新引入的基于Reactive Streams的Spring WebFlux框架,从上到下依次是R ...

  4. Electron在Windows下的环境搭建

    Electron作为一种用javascript写桌面程序的开发方式,现在已经被大众接受.下面就介绍如何在windows(>win7)下快速搭建Electron开发环境. 1. nodejs 的安 ...

  5. 实验三:klee的执行重现机制(示例分析)

    结论性内容: (1)如果是在程序中使用klee_make_symbolic,则可以使用下列脚本进行重现. export LD_LIBRARY_PATH=/home/klee/xiaojiework/k ...

  6. swoole 创建UDP服务器

    udp_server.php <?php // 创建Server对象,监听 127.0.0.1:9502端口,类型为SWOOLE_SOCK_UDP $serv = new swoole_serv ...

  7. ArrayBlockingQueue详解

    转自:https://blog.csdn.net/qq_23359777/article/details/70146778 1.介绍 ArrayBlockingQueue是一个阻塞式的队列,继承自Ab ...

  8. 新浪OAuth网络登录,请求access_token时遇到21323的错误

    按照新浪给出的文档写了,但是遇到错误,总是获取不到token值,也是post方式提交的. 查阅百度资料,发现有网友给出了解决办法,是因为 文档中有这么一句提示: HTTP请求方式:POST 这句话太简 ...

  9. Yii正则验证

    required : 必须值验证属性 [['字段名'],required,'requiredValue'=>'必填值','message'=>'提示信息']; #说明:CRequiredV ...

  10. bzoj4600 [Sdoi2016]硬币游戏

    Description Alice和Bob现在在玩的游戏,主角是依次编号为1到n的n枚硬币.每一枚硬币都有两面,我们分别称之为正面和反面.一开始的时候,有些硬币是正面向上的,有些是反面朝上的.Alic ...