c++11线程创建的三种方法

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

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

 1 #include "pch.h"
 2 #include <iostream>
 3 #include<thread>
 4 void print1()
 5 {
 6     cout << "print1_1线程执行" << endl;
 7     cout << "print1_2线程执行" << endl;
 8     cout << "print1_3线程执行" << endl;
 9 }
10 using namespace std;
11 int main()
12 {
13     thread mythread1(print1);
14     mythread1.join();
15     //mythread1.detach();
16     cout << "主线程执行" << endl;
17     return 0;
18 }

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

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

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

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

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

直接看代码:

 1 #include "pch.h"
 2 #include <iostream>
 3 #include<thread>
 4 class T
 5 {
 6 public:
 7     /*情况一:
 8     int &it;//一个进程中的所有线程共享同一块内存(内存共享),在线程中使用引用其实是不安全的
 9     T(int &m_it) :it(m_it)
10     {
11         cout << "构造函数被执行" << endl;
12     }
13     */
14     //不能用引用,应该像下面这样用
15     int it;
16     T(int m_it) :it(m_it)
17     {
18         cout << "构造函数被执行" << endl;
19     }
20     T(const T &t) :it(t.it) {
21         cout << "拷贝构造函数被执行" << endl;
22     }
23     ~T()
24     {
25         cout << "析构函数被执行" << endl;
26     }
27     void operator()()
28     {
29         cout << "it值:" << it << endl;
30     }
31 };
32 int main()
33 {
34     int itm = 8;
35     T t(itm);//调用了构造函数
36     thread mythread2(t);
37     mythread2.join();
38     //mythread2.detach();
39     cout << "主线程执行" << endl;
40     return 0;
41 }

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

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

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

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

直接看代码:

 1 #include <iostream>
 2 #include<thread>
 3 using namespace std;
 4 int main()
 5 {
 6     //用lambda表达式创建一个线程
 7     auto mylamthread = [] {//这是一个lambda表达式
 8         cout << "我的线程开始执行了" << endl;
 9         //......
10         cout << "我的线程执行结束了" << endl;
11     };
12     thread mythread3(mylamthread);
13     mythread3.join();
14     cout << "主线程执行结束" << endl;
15     return 0;//表示主线程执行结束,表明进程结束
16 }

四、认识一个函数

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

原文地址:https://www.cnblogs.com/suchang/p/10568998.html

时间: 2024-10-03 22:20:01

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

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

java多线程的难点是在:处理多个线程同步与并发运行时线程间的通信问题.java在处理线程同步时,常用方法有: 1.synchronized关键字. 2.Lock显示加锁. 3.信号量Semaphore. 线程同步问题引入: 创建一个银行账户Account类,在创建并启动100个线程往同一个Account类实例里面添加一块钱.在没有使用上面三种方法的情况下: 代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

JAVA之线程同步的三种方法

最近接触到一个图片加载的项目,其中有声明到的线程池等资源需要在系统中线程共享,所以就去研究了一下线程同步的知识,总结了三种常用的线程同步的方法,特来与大家分享一下.这三种方法分别是:synchronized代码段.synchronized修饰方法/类.ThreadLocal本地线程变量. 我们通过一个例子来表现这三种方法:一张银行卡里面有300块钱,15个线程从这张银行卡中取钱,每个线程取一次且每次取20块钱:当当前余额不足100元时,则向账户中汇款20元.三种方法每种方法都有5个线程.我们预期

解决线程安全的三种方法

1:线程安全 如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的. 我们通过一个案例,演示线程的安全问题: 电影院要卖票,我们模拟电影院的卖票过程.假设要播放的电影是 “上海堡垒”,本次电影的座位共50个(只能卖50张票). 我们来模拟电影院的售票窗口,实现多个窗口同时卖 “葫芦娃大战奥特曼”这场电影票(多个窗口一起卖这50张票)需要窗口,采用线程对象来模拟:需要票,Runnable接口子类

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

创建对象的三种方法: 1.工厂模式 工厂模式是软件工程领域广为人知的设计模式,这种模式抽象了创建具体对象的过程.下面是使用工厂函数创建对象的的一个例子. 2.构造函数: 从上面的例子中,我们看到构造函数与工厂函数不同之处: 1.没有显式的创建对象 2.直接将属性和方法赋给了this对象,没有return语句 另外,函数名Person使用了首字母大写.(这是一个惯例,构造函数始终都应该以一个大写字母开头,而非构造函数应该以一个小写字母开头.) 使用构造函数来创建对象,意味着你可以获取对象的类型.这

java_线程创建的两种方法

线程创建的方法有两种: 一 继承Thread类: public class ThreadTest { public static void main(String[] args) { //4)在main方法中创建线程对象 Thread01 thread01 = new Thread01(); //5)调用Thread的start方法启动线程并执行线程 thread01.start(); } } //1)创建一个类继承Thread类 class Thread01 extends Thread{ /

线程创建的第二种方法

第一种方法是继承并且重写run方法(不推荐使用) 第二种就是有爹的情况,用实现接口的形式拓展功能--实现Runnable接口 Runnable中只有run()方法 今天复习同步线程代码时候卡在一个问题上: class SynThread implements Runnable { run() { } } class Main { public static void main(string [] args) { SynThread syn=new SynThread(); Thread a=ne

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

线程的最大特点是资源的共享性,但资源共享中的同步问题是多线程编程的难点.linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量和信号量. 一.互斥锁(mutex) 通过锁机制实现线程间的同步. 初始化锁.在Linux下,线程的互斥量数据类型是pthread_mutex_t.在使用前,要对它进行初始化.静态分配:pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;动态分配:int pthread_mutex_init(pthread_m

Linux 线程同步的三种方法(互斥锁、条件变量、信号量)

互斥锁 1 #include <cstdio> 2 3 #include <cstdlib> 4 5 #include <unistd.h> 6 7 #include <pthread.h> 8 9 #include "iostream" 10 11 using namespace std; 12 13 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 14 15 int tmp; 16

线程 task 使用三种方法

1:用TaskFactory的实例: 运行结果为: 2. 使用task类的Factory属性 3.使用task类的实例,用start来启动任务.  当我们用Task类时,除了用start方法,也可以用RunSynchornously()方法 原文地址:https://www.cnblogs.com/bingyizhihun/p/8251681.html