C++并发与多线程C++如何线程创建线程以及函数join()和detach()用法和区别

前言:

通常一个程序运行起来,也就等于一个进程在运行,这个进程中会有一个主线程自动创建并运行,当程序的main()函数返回之后那么此主线程也就运行结束,也意味着进程运行结束。

主线程是从main()函数开始运行,main()函数就可以看做主线程的入口函数

1. C++如何创建一个线程。

创建一个最简单的线程只需要注意三点:

  • 第一:需要包含thread头文件;
  • 第二:需要提供一个线程入口函数;
  • 第三:我们直接在main函数中创建thread。
#include 
#include 

using namespace std;
void myThreadTest()
{
    cout << "the thread running..."<<endl;

    count<< "线程运行完毕"<<endl;
    return;
}

int main()
{
    //创建了线程,此处的线程入口函数则是myThreadTest,并且开始执行线程
    thread myThread(myThreadTest);

    /***
    此处可以调用join()函数和detach()函数
    join()函数可以理解为让主线程的等待该子线程完成,然后主线程再继续执行。
    detach()的作用:是将子线程和主线程的关联分离,也就是说detach()后
    子线程在后台独立继续运行,主线程无法再取得子线程的控制权,
    即使主线程结束,子线程未执行也不会结束。
    当主线程结束时,由运行时库负责清理与子线程相关的资源。
    */

    myThread.join();

    /***
    joinable()主要是用于判断是否可以成功使用join()或者detach()
    如果返回true,证明可以调用join()或者detach()
    如果返回false,证明调用过join()或者detach(),就不能再调用了join()和detach()
    */

    if(myThread.joinable())
    {
        cout<<"这里可以调用函数join()或detach()"<<endl;
    }
    else
    {
        cout<<"反之,不能调用函数join()和detach()"<<endl;
    }
    return 0;
}

可以看到,线程类参数其实是一个可调用对象。c++中可调用对象可以是函数、函数指针、lambda表达式、bind创建的对象或者重载了函数调用运算符的类对象。

2.其他创建线程的方法:

那么也就意味着还有其他创建线程的方法:

#include 
#include 
#include 

using namespace std;

//方法一:重载了函数调用运算符的类对象,此类中编写了圆括号重载函数,
//然后可以创建该类的对象,并将此对象作为线程入口地址
class myThreadTest
{
public:
    void operator()()
{
        cout<<"测试使用圆括号重载函数方法..."<<endl;

        cout<<"次函数运行结束"<<endl;
    }
};

//方法三:把某个类中的某个函数作为线程的入口地址

class myThreadTest2
{
public:
    void pushNumber()
{
        cout<<"push one number"<<endl;
    }
    void popNumber()
{
        cout<<"pop one number"<<endl;
    }
};

void myThreadTest()
{
    cout << "the thread running..."<<endl;

    count<< "线程运行完毕"<<endl;
    return;
}

int main()
{
    //创建了线程,此处的线程入口函数则是myThreadTest,并且开始执行线程
    thread myThread(myThreadTest);

    /***
    此处可以调用join()函数和detach()函数
    join()函数可以理解为让主线程的等待该子线程完成,然后主线程再继续执行。
    detach()的作用:是将子线程和主线程的关联分离,也就是说detach()后
    子线程在后台独立继续运行,主线程无法再取得子线程的控制权,
    即使主线程结束,子线程未执行也不会结束。
    当主线程结束时,由运行时库负责清理与子线程相关的资源。
    */

    myThread.join();

    /***
    joinable()主要是用于判断是否可以成功使用join()或者detach()
    如果返回true,证明可以调用join()或者detach()
    如果返回false,证明调用过join()或者detach(),就不能再调用了join()和detach()
    */

    if(myThread.joinable())
    {
        cout<<"这里可以调用函数join()或detach()"<<endl;
    }
    else
    {
        cout<<"反之,不能调用函数join()和detach()"<<endl;
    }

    myThreadTest myThreadObj;
    thread myThread2(myThreadObj);
    myThread2.detach();


    //方法二: 创建lambda表达式
    auto lambdaThreadTest = []{
        cout <<"创建lambda表示进行测试"<<endl;
    };
    thread myThread3(lambdaThreadTest);
    myThread3.join();

    /***
    方法三:
    第一个&意思是取址,第二个&意思是引用,相当于std::ref(s)
    thread oneobj(&Data_::SaveMsh,s)传值也是可以的
    在其他的构造函数中&obj是不会代表引用的,会被当成取地址
    */
    myThreadTest2 myThreadT2;
    thread myThread4(&myThreadTest2::pushNumber,&myThread2);
    thread myThread5(&myThreadTest2::popNumber,&myThread2);

    myThread4.join();
    myThread5.join();

    return 0;
}

你可能感兴趣的:(C++笔记,c++,算法,开发语言)