C++并行开发2-线程启动、结束,创建线程多法、join,detach

FengLY Lv3

创建线程的简单演示

  • 首先,在一个程序中一个进程结束的标志是main函数执行结束,因此在正常情况下,当主线程执行完毕后,其他子线程如果没有执行完毕,也会被操作系统强行关闭

  • 自己创建的进程也是从一个函数开始

thread

thread是一个类,只能接收 可调用的对象

join()

join 加入,是阻塞意思,让主线程等待所有子线程运行结束后,才开始执行主线程

detach()

detach, 是分离的意思,让主线程不用等待子线程运行结束,就可以直接退出
子线程并没有结束,没有结束的部分,由C++运行时库接管,但是已经和主函数失去联系,并且由操作系统释放资源

#include <iostream>
#include <thread>

using namespace std;

void myPrint()
{
    cout << "线程开始 " << endl;
    //....
    //....
    //while (1);

    cout << "线程结束  " << endl;
}

int main()
{   
    //(1) thread 是C++标准库里面的一个类
    //(2) join 加入,是阻塞意思,让主线程等待所有子线程运行结束后,才开始执行主线程
    //(3) detach, 是分离的意思,让主线程不用等待子线程运行结束,就可以直接退出
    //(4) joinable 判断当前子线程能否join 或者 detach; 
    // 子线程并没有结束,没有结束的部分,由C++运行时库接管,但是已经和主函数失去联系,并且由操作系统释放资源
    thread mytobj = thread(myPrint);  //(1)创建了一个线程,(2)并且线程myPrint开始执行 
    //F9 加入断点   F10逐行运行

    if (mytobj.joinable()) {
        cout << "1可以并发 " << endl;
    }
    else {
        cout << "1不可以并发 " << endl;
    }

    mytobj.join();
    //mytobj.detach();

    if (mytobj.joinable()) {
        cout << "2可以并发 " << endl;
    }
    else {
        cout << "2不可以并发 " << endl;
    }
    cout << "main over" << endl;
    return 0;
}
  1. 一个线程thread类创建的地方也是这个类所在函数开始执行的地方
  2. join的作用是让主线程等待main主线程运行完毕。
  3. 将上例中的join注释掉就会发现,myprint是执行了,但是会报错,因此主线程已经退出了

当不加join 和 detach的时候:此时主线程提前退出,并没有等待子线程 F:/网站备份-20221127/zhouaq_backup_20221127.com/zhouaq.com/wp-content/候,主线程等待子线程 F:/网站备份-20221127/zhouaq_backup_20221127.com/zhouaq.com/wp-content/的时候,主线程已经结束完毕,并且退出,但是子线程并没有运行结束(没有执行线程结束)
joinable的状态 [![](http://zhouaq.com/wp-
content/uploads/2020/09/wp_editor_md_3222d5fd43f6d78bae3f5bf7f2e86e2c.jpg)](http://zhouaq.com/wp-
content/uploads/2020/09/wp_editor_md_3222d5fd43f6d78bae3f5bf7f2e86e2c.jpg)

其他方式创建线程调用对象

类对象

#include <iostream>
#include <thread>

using namespace std;

class TA {
public: 
    int &m_i;  //引用存在潜在问题
    TA(int &i) : m_i(i) {
        cout << "构造创建对象" << endl;
    }  //如果用detach 传引用的情况下,如果主线程退出,那么这个引用的内存也被销毁,会产生不可预料的问题

    TA(const TA& other):m_i(other.m_i) {
        cout << "拷贝构造对象" << endl;
    }

    ~TA() {
        cout << "析构函数" << endl;
    }
    void operator()() {  //重载()
        cout << "线程开始 " << endl;
        //....
        //....
        //while (1);
        cout << "m_i 1" << m_i << endl;
        cout << "m_i 2" << m_i << endl;
        cout << "m_i 3" << m_i << endl;
        cout << "m_i 4" << m_i << endl;

        cout << "线程结束  " << endl;
    }
};

但是在调用类对象中由一些潜在可能存在的问题,当传引用的时候,如果主线程退出,那么子线程也有可能会被退出 在调用类对象的时候,会调用拷贝构造函数需要注意

使用lambda创建线程

int main() {

    //使用lambda表达式
    auto lambdaThread = [] {
        cout << "lambda 子线程" << endl;
    };
    thread myobj4(lambdaThread);  //这个对象是被复制导进程
    myobj4.detach();
    cout << "main over " << endl;
    return 0;
}
  • Title: C++并行开发2-线程启动、结束,创建线程多法、join,detach
  • Author: FengLY
  • Created at : 2023-06-18 22:40:09
  • Updated at : 2023-06-18 22:55:16
  • Link: https://zhouaq.com/2023/06/18/C++并行开发2-线程启动、结束,创建线程多法、join,detach/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments
On this page
C++并行开发2-线程启动、结束,创建线程多法、join,detach