并发与多线程二:线程启动、结,创建线程方法,join,deteach

//#include <iostream>
//#include <vector>
//#include <map>
//#include <string>
//#include <thread>
//
//using namespace std;
//
////自己创建的线程也要从一个函数开始运行
////void myprint()
////{
////    cout << "我的线程开始执行了" << endl;
////
////    //...
////    //..
////    cout << "我的线程结束了" << endl;
////    cout << "我的线程结束了1" << endl;
////    cout << "我的线程结束了2" << endl;
////    cout << "我的线程结束了3" << endl;
////    cout << "我的线程结束了4" << endl;
////    cout << "我的线程结束了5" << endl;
////    cout << "我的线程结束了6" << endl;
////    cout << "我的线程结束了7" << endl;
////    cout << "我的线程结束了1" << endl;
////    cout << "我的线程结束了2" << endl;
////    cout << "我的线程结束了3" << endl;
////    cout << "我的线程结束了4" << endl;
////    cout << "我的线程结束了5" << endl;
////    cout << "我的线程结束了6" << endl;
////    cout << "我的线程结束了7" << endl;
////}
////class TA
////{
////public:
////    int &m_i;//这里定义一个引用变量
////    //TA(int &i):m_i(i){}//这里对引用变量赋值,m_i就是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()()//这里是仿函数,模仿函数的类,使用方式如同函数,本质是类中重载括弧运算符operator();
////    {
////        //cout << "我的线程开始执行了" << endl;
////
////        //cout << "我的线程结束了" << endl;
////        cout << "m_i1的值为:" << m_i << endl;//这里用了引用(所以别用),再detach状态下,主线程执行完了,这里
////        cout << "m_i2的值为:" << m_i << endl;//的m_i还在引用myi,而myi已经被释放,所以可能产生不可预料的结果
////        cout << "m_i3的值为:" << m_i << endl;
////        cout << "m_i4的值为:" << m_i << endl;
////        cout << "m_i5的值为:" << m_i << endl;
////
////    }
////};
//int main()
//{
//    //范例演示线程运行的开始和结束
//    //程序运行起来,生成一个进程,该进程所属的主线程开始自动运行;
//    //cout<<"I love china"<<endl;//实际上这是主线程在执行,主线程从main()函数返回,则整个程序执行完毕
//    //主线程从main()函数开始执行,那么我们自己创建的线程,也需要从一个函数开始执行(初始函数),一旦这个函数执行完毕,
//    //就代表我们这个线程运行结束
//
//    //整个进程是否执行完毕的标志事 主线程是否执行完毕,如果主线程执行完毕了,就代表整个线程执行完毕了。
//    //此时,一般情况下,如果其他子线程没有执行完毕,那么那些子线程也会被操作系统强行终止。
//    //所以,一般情况下,我们得到一个结论:如果大家保持子线程的运行状态,那么要让主线程一直保持运行
//
//    //a)包含一个头文件thread
//    //b)初始函数要写。
//    //c)main中开始写代码
//    //大家必须明确一点:有两个线程在跑,相当于整个程序有两条线在同时走,所以,可以同时干两件事。
//    //即使一条线被堵住了,另一条线还是可以通信
//    //(1.1)thread:是标准库里的类
//    //(1.2)join():加入汇合,说白了就是阻塞,阻塞主线程,让主线程等待子线程执行完毕,然后子线程和主线程汇合,然后主线程再往下走
//    //一个良好的程序,应该是主线程等待子线程执行完毕,自己才开始最终退出
//    //(1.3)detecth():传统多线程程序主线程要等待子线程执行完毕,自己才最终退出
//    //detecth:分离,也就是主线程不和子线程汇合了,各自执行,主线程不必等待子线程
//    //为什么引入detecth:我们创建了很多子线程,让主线程逐个等待子线程结束,这个变成方法不太好,所以才引入
//    //一旦detecth之后,与这个主线程关联的thread对象就会失去与这个主线程的关联,此时这个子线程就会驻留在后台运行(主线程与子线程失去联系)
//    //这个子线程就相当于被c++运行时库接管,当这个子线程执行完毕后,由运行时库负责清理该线程相关的资源(守护线程)。
//    //detach是线程myprint失去我们自己的控制。
//    //(1.4)joinable():判断是否可以成功join()或者detach的;返回ture或false
//
//
//    //myprint可调用对象。
//    //thread mytobj(myprint);//创建了线程,线程执行起点(入口)myprint(),(2)myprint线程开始执行
//    //if(mytobj.joinable())
//    //{
//    //    cout << "2:jpinable()==true" << endl;
//
//    //}
//    //else
//    //{
//    //    cout<< "2:jpinable()==false" << endl;
//    //}
//    //阻塞主线程并等待myprint子线程执行完
//    //mytobj.join();//当子线程执行完毕,这个join()就执行完毕,主线程就继续往下走
//
//
//    //mytobj.detach();//一旦调用了detach,就不能再用join,否则系统会报异常,有可能主线程执行完了子线程没执行完。
//    //if (mytobj.joinable())
//    //{
//    //    cout << "2:jpinable()==true" << endl;
//    //    //mytobj.join();
//
//    //}
//    //else
//    //{
//    //    cout << "2:jpinable()==false" << endl;
//    //}
//    //cout << "I love china" << endl;
//    //cout << "I love china1" << endl;
//    //cout << "I love china2" << endl;
//    //cout << "I love china3" << endl;
//    //cout << "I love china4" << endl;
//    //cout << "I love china5" << endl;
//
//
//    //二:其他创建线程的手法
//    //(2.1)用类,以及一个问题范例
//    //疑问:一旦调用了detach(),那么主线程执行结束了,我这里用这个ta这个对象还在吗?
//    //这个对象实际上时被复制到线程中去,执行完主线程后,ta被销毁,但是所复制的TA对象依旧存在,运行程序发现拷贝构造函数被执行,
//    //运行程序出现了两次析构,一次是复制进去的TA对象的析构,一次是ta原对象的析构
//    //所以只要你这个TA类对象没有引用,没有指针,那么就不会产生问题。
//    //int myi = 6;
//    //TA ta(myi);
//    //thread mytobj3(ta);//ta:可调用对象。
//    ////mytobj3.join();//等待子线程执行结束。
//    //mytobj3.detach();
//    //cout << "I love china" << endl;
//
//    //(2.2)用lambda表达式
//    auto mylamthread = []{
//        cout << "我的线程开始执行了" << endl;
//        
//        cout << "我的线程结束了" << endl;
//    };
//    thread mytobj4(mylamthread);
//    mytobj4.join();
//
//    return 0;
//}

posted @ 2020-09-28 15:32  AI_ON  阅读(89)  评论(0)    收藏  举报