多线程编程1

  1. 运行起来的程序就是进程,每个进程都有一个主线程,主线程运行完毕,则进程结束
  2. 可以自己写代码来运行子线程,一般情况下,主线程运行结束后,子线程就也随之结束
  3. 一般情况下,使用join函数,使主线程等待子线程运行结束后再运行
  4. 使用detach函数,可使主线程和子线程各自独立运行,互不影响各自生命周期, 但这样主线程结束后,子线程的输出转到后台进行无法在输出在屏幕上,不好监控,不推荐
  5. 线程参数:必须是一个可调用对象(函数、函数指针、lambda表达式、bind创建的对象、其他重载了函数调用运算符的类对象)
#include <iostream>
#include <thread>

using namespace std;

//使用函数来创建线程
void myPrint(){
    cout << "函数 我的线程开始运行啦 " << endl;
    cout << "函数 我的线程运行结束啦" << endl;
}

//使用重载操作符类对象来创建线程
class TA{
    public:
    //int &m_i; //定义一个引用类型的成员变量
    int m_1i;   //定义一个普通类型的变量,将值拷贝过来,就不会发生错误
                //通过引用主函数将myi的值传给i,i再将其赋给m_1i,只有m_1i不为引用,不把i(即myi)的地址赋过去,就没有问题
    TA(int &i):m_1i(i) {  //使用主函数传过来的i来给m_i赋值,构造函数 ;若i不为引用类型变量,则i的输出为6487528类错地址
        cout << "TA()构造函数被执行" << endl;
    } 
    TA(const TA &ta):m_1i(ta.m_1i){
        cout << "TA()拷贝构造函数被执行" << endl;
    }  
    ~TA(){
        cout << "TA()析构函数被执行" << endl;
    }

    void operator( )(){ //第一个(),重载运算符() ;第二个(),不给重载的运算符传入参数
    //cout << "类重载操作符 我的线程开始运行啦" << endl;
    //cout << "类重载操作符 我的线程结束运行啦" << endl;

    cout << "m_i 1 的值为 " << m_1i << endl;
    cout << "m_i 2 的值为 " << m_1i << endl;
    cout << "m_i 3 的值为 " << m_1i << endl;
    cout << "m_i 4 的值为 " << m_1i << endl;
    }
};

//使用lambda运算符来创建线程(见main函数内)


//使用类中某个函数的入口作为线程的入口地址
class Data{
    public:
    void GetMsg()  { cout << "将Data类中的GetMsg函数作为线程入口" << endl; }
    void SaveMsh() { cout << "将Data类中的SaveMsg函数作为线程入口" << endl; } 
};





int main(){
    //创建线程myPrint
    //1. 线程执行的起点(入口)是myPrint; 2. 执行线程
    
    thread myThread1(myPrint);

    
    //jion:汇合,主线程等待子线程与其汇合
    //阻塞主线程并等待线程myPrint执行完毕,当myPrint执行完毕后,主线程继续往下执行
    myThread1.join();

    
    //joinable()用来判断jion/detach是否调用成功
    //g++ 中调用成功则返回0,失败返回1
    if ( !myThread1.joinable() ){
        cout << "成功调用 join()" << endl;
    }else{
        cout << "不能调用 jion()" << endl;
    }
    
    /*
    //detach:分离
    //主线程和子线程分离,主线程不再等待子线程执行完毕再结束,
    //detach后主线程和子线程失去联系,子线程驻留在后台,由c++运行库接管
    myThread1.detach();
    
    if ( !myThread1.joinable() ){
        cout << "成功调用了detach()" << endl;
    }else{
        cout << "不能调用detach()" << endl;
    }
    */

   //使用lambda函数来创建线程
    auto lambdaThread = []{
        cout << "lambda表达式 我的线程开始运行啦 " << endl;
        cout << "lambda表达式 我的线程结束运行啦 " << endl;
    };

    thread myThread3(lambdaThread);
    myThread3.join();
    
    int myi = 9;
    TA ta(myi);
    thread myThread2(ta); //将主线程中的ta复制到子线程,所以即使主线程结束,ta被销毁,ta的复制仍能运行,因为是复制,所以会调用拷贝构造函数
   // myThread2.join();  //对于引用的参数,使用join使主线程等待子线程可以获得1~4输出
    myThread2.detach();  //引用参数将地址传给子线程的函数,在主线程执行完毕后主线程的资源被释放
                        //myi的值内存被回收了,使用复制即可解决这个问题
                        //只要TA类对象没有引用和指针就能正常   

    Data s;
    thread oneobj(&Data::GetMsg, &s);
    thread twoobj(&Data::SaveMsh, &s);
    oneobj.join();
    twoobj.join();
    cout << " 在主线程中: I love China !" << endl;


    //执行完return 0主线程才算执行完毕
    return 0 ;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值