zoukankan      html  css  js  c++  java
  • C++11线程创建的三种方法

    原文链接https://www.cnblogs.com/suchang/p/10568998.html
     
    一、用一个初始函数创建一个线程

    直接看代码:注意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.

    你只管努力,剩下的交给天意!
  • 相关阅读:
    public、private、protected继承的规则
    派生类对象的构造函数与析构函数
    类的保护成员
    派生类覆盖(修改)基类成员
    条款03:尽可能使用const
    处理类与类之间的关系
    继承派生基本概念
    条款02:尽量以const,enum,inline替换#define(宁可编译器替代预处理器)
    Redis持久化AOF和RDB对比
    Memcached取模算法
  • 原文地址:https://www.cnblogs.com/wal1317-59/p/11967864.html
Copyright © 2011-2022 走看看