c++11线程创建的三种方法
一、用一个初始函数创建一个线程
直接看代码:注意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 ⁢//一个进程中的所有线程共享同一块内存(内存共享),在线程中使用引用其实是不安全的
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线程创建的三种方法的更多相关文章
- 线程创建的三种方法:继承Thread类,实现Runnable接口,实现Callable接口
线程创建 三种创建方式 1. 继承Thread类 自定义线程类继承Thread类 重写run()方法,编写线程执行体 创建线程对象,调用start()方法启动线程 线程不一定执行,CPU按排调度 pa ...
- java多线程二之线程同步的三种方法
java多线程的难点是在:处理多个线程同步与并发运行时线程间的通信问题.java在处理线程同步时,常用方法有: 1.synchronized关键字. 2.Lock显示加锁. 3.信号量Se ...
- JAVA之线程同步的三种方法
最近接触到一个图片加载的项目,其中有声明到的线程池等资源需要在系统中线程共享,所以就去研究了一下线程同步的知识,总结了三种常用的线程同步的方法,特来与大家分享一下.这三种方法分别是:synchroni ...
- JavaScript高级程序设计--对象创建的三种方法
创建对象的三种方法: 1.工厂模式 工厂模式是软件工程领域广为人知的设计模式,这种模式抽象了创建具体对象的过程.下面是使用工厂函数创建对象的的一个例子. 2.构造函数: 从上面的例子中,我们看到构造函 ...
- Java中实现线程同步的三种方法
实现同步的三种方法 多线程共享数据时,会发生线程不安全的情况,多线程共享数据必须同步. 实现同步的三种方法: 使用同步代码块 使用同步方法 使用互斥锁ReetrantLock(更灵活的代码控制) 代码 ...
- AJPFX总结线程创建的两种方法
创建线程的第一种方式:继承Thread ,由子类复写run方法.步骤:1,定义类继承Thread类:2,目的是复写run方法,将要让线程运行的代码都存储到run方法中:3,通过创建Thread类的子类 ...
- java_线程创建的两种方法
线程创建的方法有两种: 一 继承Thread类: public class ThreadTest { public static void main(String[] args) { //4)在mai ...
- java_线程创建的三种方式及区别
java中关于线程的创建有三种: (1)通过继承Thread类创建线程. (2)通过实现Runnable接口创建线程. (3)通过Callable 和 Future 接口创建线程. * * * * * ...
- 【转】 Linux 线程同步的三种方法
线程的最大特点是资源的共享性,但资源共享中的同步问题是多线程编程的难点.linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量和信号量. 一.互斥锁(mutex) 通过锁机制实现线程间的 ...
随机推荐
- html dl dt dd 标签语法与使用
一.dl dt dd认识 html <dl> <dt> <dd>是一组合标 […]
- Windows API 编程-----Windows NT 环境下禁止任务切换
函数原型: BOOL WINAPI SystemParametersInfo( _In_ UINT uiAction, _In_ UINT uiParam, _Inout_ PVOID pvParam ...
- roadflow asp.net core版工作流引擎更新发布
ROADFLOW CORE (.NET CORE工作流引擎)更新说明 1.RoadFlow全新工作流平台采用.NET CORE 2.1重构,结构更简单,逻辑梳理更清析,性能有了很大的提升. 2.表单设 ...
- 【Udacity】解决:字幕遮挡视频内容怎么办?Udacity字幕大小调整
字幕有没有办法显示在最下方,否则把内容挡住了,根本看不清老师所指的内容 Chrome 的小插件,能方便地调节视频的字幕大小,譬如:Udacity 的学习视频字幕大小不能调节,有时候不想它占太多位置,而 ...
- web安全-XSS
了解XSS的定义 跨站脚本攻击(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS.恶意攻 ...
- 第四次作业——第一次scrum冲刺
1.小组第一次冲刺任务 对Github上的HUSTOJ开源项目进行Fork,搭建基本环境 2.用户需求 (1)部分基本功能显示在首页 (2)能够提交题目并判题,并对自己所提交的题目正确性进行反馈,能够 ...
- 动态注册broadcast的安全考虑
一.android service通知activity更新方式有1. service 通过广播的形式发送broadcast,向这个activity的内部类发广播的消息来更新界面2. service直接 ...
- Django_MTV模型
创建DJango项目过程: 1:安装Django包 方式一:pip3 install django 方式二:pycharm-->file--->settings-->找到projec ...
- androidtab
https://github.com/H07000223/FlycoTabLayout tensorflow https://github.com/topics/tensorflow-examples ...
- 使用cocostudio 需要在Android.mk文件的配置
直接贴上Android.mk文件吧. 对了,是cocos2d3.0的,不知道2.x是否一样. LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LO ...