C++11多线程编程 2.线程启动,创建,结束

tech2025-02-28  3

#include<iostream> #include<thread> using namespace std; //自己创建的线程也要从一个函数(初始函数)开始执行 void myprint(){     cout << "我的线程开始了1111" << endl;     cout << "我的线程执行完毕了1111" << endl;     cout << "我的线程开始了2222" << endl;     cout << "我的线程执行完毕了2222" << endl;     cout << "我的线程开始了3333" << endl;     cout << "我的线程执行完毕了3333" << endl;     cout << "我的线程开始了4444" << endl;     cout << "我的线程执行完毕了4444" << endl; } class TA { public:     int& m_i;     TA(int& i) :m_i(i) {         cout << "TA()的构造函数执行" << endl;     }     TA(const TA& ta) :m_i(ta.m_i){         cout << "TA()的拷贝构造函数执行" << endl;     }     ~TA() {         cout << "TA()的析构函数执行" << endl;

    }     void operator()()//不能带参数     {         cout << m_i << endl;//会产生不可预料的结果,主线程执行完后悔释放myi这个时候如果用myi变量,就会出问题,如果值传递就没关系,相当于拷贝过来的两份内存。         cout << "我的1111类线程开始了" << endl;         cout << "我的1111类线程结束了" << endl;         cout << "我的2222类线程开始了" << endl;         cout << "我的2222类线程结束了" << endl;          cout << "我的3333类线程开始了" << endl;         cout << "我的3333类线程结束了" << endl;         cout << "我的4444类线程开始了" << endl;         cout << "我的4444类线程结束了" << endl;     } }; int main() {     /*    (1)范例演示线程运行的开始和结束     *    程序运行起来,生成一个进程,该进程所属的主线程开始自动执行。             (1.1)thread             (1.2)join()             (1.3)detach()             (1.4)joinable()         (2)其他创建线程的手法             (2.1)用类,以及一个问题范例             (2.2)用lambda表达式     */     //cout << "I love china" << endl;//实际上是主线程在执行,从main到返回,则整个进程执行完毕

    //主线程从main函数开始执行,我们自己创建的线程,也需要从一个函数开始执行(初始函数),一旦这个函数运行完毕,则代表着这个线程运行结束。     //整个进程是否执行完毕的标志是主线程是否执行,如果主线程执行完毕了,就代表整个进程执行完毕。     //此时,一般情况下:如果其他子线程还没有执行完毕,那么这些子线程也会被操作系统强行终止。     //所以,一般情况下,如果大家想保持子线程的运行状态,那么就要让主线程(用代码创建的线程)一直爆出运行,不能让其运行完毕。     //这条规律有意外,后续会解释,目前先这么理解

    //a)包含一个头文件thread     //b)初始函数要写     //c)main中开始写代码     //必须明确一点:有两个线程在跑,相当整个程序的 执行有两条线在同时走,所以,可以同时做两个事情。即使一条线被堵住了,另外一条线还是可以通行。这就是多线程          //(1.1)thread:是个标准库里的类     //(1.2)join():加入汇合,说白了就是阻塞,阻塞主线程,让主线程等待子线程执行完毕,然后子线程和主线程汇合, 然后主线程再往下走。     //如果主线程执行完毕了,但子线程没执行完毕,这种程序是不合格的,也是不稳定的     //一个书写良好的程序,应该是主线程等待子线程执行完毕后,自己才能最终退出。     //(1.3)detach():传统多线程程序在主线程要等待子线程执行完毕,然后自己再最后退出。     //datach:分离   主线程不和子线程汇合了,你主线程执行你的,我子线程执行我的,你主线程也不必等我子线程运行结束,你可以先执行结束,这并不影响子线程的执行。     //为什么引入detach():我们创建了很多子线程,让主线程逐个等待子线程结束,这种编程方法不太好,所以引入了detach();     //一旦detach()之后,与这个主线程关联的thread对象就会失去与这个主线程的关联,此时这个子线程就会驻留在后台运行了(主线程与该子线程失去联系)。     //这个子线程就相当于被C++运行时库接管,当这个子线程执行完成后,由运行时库负责清理该线程相关的资源(守护线程)。     //detach()使线程myprint失去我们自己的控制。     //(1.4)joinable()判断是否可以成功使用join()或者detach()的,返回true或者false     //

    //myprint是一个可调用对象     std::thread mytobj(myprint);//(1)创建了线程,线程执行起点(入口)myprint(); (2)myprint()线程开始执行     //阻塞主线程并等待myprint子线程执行完。     /*mytobj.join();*///主线程阻塞到这里等待myprint()执行完。当子线程执行完毕。这个join()就执行完毕,主线程就开始继续执行     mytobj.detach();//一旦调用detach()就不能再join回来了,不能再用join(),否则系统会报告异常     if (mytobj.joinable())     {         cout << "可以使用join或者detach" << endl;     }     else     {         cout << "不能使用join或者detach" << endl;     }     cout << "主线程收尾,最终主线程安全退出1" << endl;     cout << "主线程收尾,最终主线程安全退出2" << endl;     cout << "主线程收尾,最终主线程安全退出3" << endl;     cout << "主线程收尾,最终主线程安全退出4" << endl;     cout << "主线程收尾,最终主线程安全退出5" << endl;

    /*二:其他创建线程的手法         (2.1)用类,以及问题范例             问题:一旦调用了detach(),那我主线程执行结束了,我这里用的这个ta对象还在吗?(对象不在了)             答案:这个对象实际上是被赋值到线程中去;所以执行完主线程后,ta会被销毁,但是所赋值的ta对象依旧存在                   所以,只要这个TA类对象里面没有引用,没有指针,那么就不会产生问题。     */     int myi = 6;     TA ta(myi);     thread mytobj3(ta);     mytobj3.detach();

    //(2.2)用lambda表达式创建     auto mylamthread = [] {         cout << "我的线程3开始执行了" << endl;

        cout << "我的线程3执行结束了了" << endl;     };     thread mytobj4(mylamthread);     mytobj4.join();

    cout << "I LOVE CHINA" << endl;     cout << "I LOVE CHINA" << endl;     cout << "I LOVE CHINA" << endl;     cout << "I LOVE CHINA" << endl;     cout << "I LOVE CHINA" << endl;     return 0;

}

最新回复(0)