c++11多线程编程(二)线程启动,结束,创建线程多法,join,detach


一、范例演示线程运行的开始和结束

1.thread

2.join()

3.detach()

4.joinable()

  • 线程运行起来,生成一个进程,该进程所属的主线程开始自动运行。
  • 主线程从main()函数开始执行,自己创建的线程,也需要从一个函数开始运行(初始函数),一旦这个函数运行完毕。该线程也结束。
  • 整个进程是否执行完毕的标志:主线程是否执行完毕,如果主线程执行完毕了,那就代表整个进行执行完毕。此时,如果其他子线程还没有执行完毕,那么这些子线程也会被操作系统强行终止(一般情况)。所以,一般情况下,如果想保持子线程运行状态,则主线程应一直保持运行。
  • 例外:detach(),传统程序主线程要等待子线程运行完毕,然后自己在最后退出;detach()主线程和子线程汇合,主线成也不必等待子线程运行结束。(建议主线程等待所有子线程);一旦detach()之后,与主线程关联的thread对象就会失去与主线程的关联关系,此时子线程就会驻留在后台运行(相当于被c++运行时刻接管,当子线程执行完毕后,由运行时库清理该线程相关的资源(变成守护线程))。不能detach()后再用join();joinable():判断是否可以成功使用join()或者detach(),返回true()表示可以join()或者detach();返回false不能join();
  • 创建过程
    1. 包含头文件“thread”;
    2. 初始函数;
    3. 在main中写代码;

代码如下:

# include <thread>
#include <iostream>

using namespace std;

void my_print()
{
         cout  << "我的线程开始执行了"  << endl;
         cout << "我的线程执行完毕了"  << endl;
}

int main()
{
        //创建了线程,线程执行入口是 my_print()
        //thread: 标准库中的类,用于创建线程;
        //my_print 是一个可调用对象
        thread myobj(my_print);
        //阻塞主线程,让主线程等子线程执行完毕
        //然后子线程和主线程汇合,主线程再往下走
        //去掉后会导致程序执行混乱
        //主线程阻塞在这里,等待my_print()执行完毕
        myobj.join();
        cout << "主程序正常退出" << endl;
}

注:代码有两条线路,两个线程在跑,所以,可以同时干两件事,即使一条线被堵住了,另外一条线还是可以通行的;如果主线程执行完毕,主线程执行完毕,程序是不稳定的;一个书写良好的程序,应该是主线程等待子线程执行完毕后,自己再终止;

二、其他创建线程的方法

1.用类以及一个问题范例

类:必须是一个可调用类对像,必须复写一下operator()()这个函数;用类创建线程,则operator()()为执行的入口点;
代码如下:

# include <thread>
#include <iostream>

using namespace std;

class TA
{
       public:
               void operator()()
               {
                        cout  << "我的线程开始执行了"  << endl;
                        cout << "我的线程执行完毕了"  << endl;
               }
}

int main()
{
       TA ta;
        thread myobj(ta);  //ta是可调用对象
        myobj.join();  //等待子线程执行结束
        cout << "主程序正常退出" << endl;
}

用例分析:

# include <thread>
#include <iostream>

using namespace std;

class TA
{
       public:
               int &m_i;  //如果不是引用则正常,这样用是一个bug
               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_i1 的值为:" << m_i  <<  endl;
                        cout  << "m_i2 的值为:" << m_i  <<  endl;
                        cout  << "m_i3 的值为:" << m_i  <<  endl;
                        cout  << "m_i4 的值为:" << m_i  <<  endl;
                        cout  << "m_i5 的值为:" << m_i  <<  endl;
                        cout  << "m_i6 的值为:" << m_i  <<  endl;
               }
}

int main()
{
       int myi = 6; //主线程的局部变量,当主线程执行结束,myi被回收;
       TA ta(myi);  //对象也是局部的,所以主线程结束后,ta被回收;执行的析构函数析构的是主线程的ta;
       //但是这个对象实际上会被复制到线程中,所以子线程可以继续运行;
       //所以线程中没有引用/指针就不会产生问题;
        thread myobj(ta);  //ta是可调用对象
        myobj.detach();  //等待子线程执行结束
        // myobj.join(); //如果正常等待子线程,则会析构两次ta;
        cout << "主程序正常退出" << endl;
}

2.用lambda表达式

# include <thread>
#include <iostream>

using namespace std;

int main()
{
       auto mylamthread = [] 
       {
                cout  << "我的线程开始执行了"  << endl;
                 cout << "我的线程执行完毕了"  << endl;
       }
        thread myobj(mylamthread);  //ta是可调用对象
        myobj.join();  //等待子线程执行结束
        cout << "主程序正常退出" << endl;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值