C++并发多线程学习记录(一)

thread创建线程三种方式、join、detach关键字

通过函数创建一个线程

先上代码

#include <iostream>
#include <thread>

using namespace std;

void mythread()
{
    cout << "我是子线程,执行完毕!\n"<<endl;
}
int main()
{    
    //thread+线程对象名(函数名)创建线程
    thread mthread(mythread);
    mthread.join();

    cout << "我是主线程,已经执行完毕!\n";
    return 0;
}

执行结果

一个线程就是干一件事,那么就需要有一个执行函数,mythread()就是执行函数,功能就是输出一句话。join关键字的作用就是阻塞主线程,等待子线程结束之后,在回来继续执行主线程。若不加jion()关键字,就会出现运行报错,主线程和子线程随机切换执行的情况。

datach()

一般情况来说,在主线程的结束之后,子线程就会被强制结束。特殊的可以用detach关键字,将子线程的管理权从主线程转变到运行时库。这样主线程和子线程分离,主线程结束之后,不会影响子线程继续执行(子线程转入后台执行,由运行时库清理相关资源)

代码

#include <iostream>
#include <thread>

using namespace std;

void mythread()
{
    cout << "我是子线程a!\n"<<endl;
    cout << "我是子线程b!\n" << endl;
    cout << "我是子线程c!\n" << endl;
    cout << "我是子线程d!\n" << endl;
    cout << "我是子线程e!\n" << endl;
    cout << "我是子线程f!\n" << endl;
    cout << "我是子线程g!\n" << endl;
    cout << "我是子线程h!\n" << endl;
}
int main()
{
    thread mthread(mythread);
    //mthread.join();
    mthread.detach();

    cout << "我是主线程1!\n";
    cout << "我是主线程2!\n";
    //让主线程休眠200毫秒,否则主线程进行太子线程还没轮上,打印窗口就关闭了
    //打印窗口是跟着主线程一块的,主线程退出,窗口就退出
    std::this_thread::sleep_for(std::chrono::milliseconds(200));
    cout << "我是主线程3!\n";
    cout << "我是主线程4!\n";
    cout << "我是主线程5!\n";
    cout << "我是主线程6!\n";
    return 0;
}


结果

 joinable()

要注意,对一个线程,join和detach只能用一次,不能同时使用否则会运行异常。可以通过joinable()判读程序是否可以join或者detach,若可以咋返回true否则返回false;

代码

#include <iostream>
#include <thread>

using namespace std;

void mythread()
{
    cout << "我是子线程a!\n"<<endl;
}
int main()
{
    thread mthread(mythread);
    //mthread.join();

    cout << "joinable值为:" << mthread.joinable() << endl;
    mthread.detach();
    cout << "joinable值为:" << mthread.joinable() << endl;

    cout << "我是主线程1!\n";
    return 0;
}

结果

通过类创建一个线程

 代码如下 

#include <iostream>
#include <thread>

using namespace std;


class Lei
{
public:
    int m_i;
    Lei(int& i) :m_i(i)
    {
        cout << "lei构造函数被执行" << endl;
    }
    Lei(const Lei& lei) :m_i(lei.m_i)
    {
        cout << "lei拷贝构造函数被执行" << endl;
    }

    ~Lei()
    {
        cout << "lei析构函数被执行" << endl;
    }
    //执行类的功能
    void operator()()
    {
        cout << "operator()函数被执行" << endl;
    }

};


int main()
{
    int myi = 6;
    Lei lei = Lei(myi);
    //将类作为参数 创建一个线程
    thread mthread(lei);
    mthread.join();

    cout << "我是主线程1!\n";
    return 0;
}


执行结果

分析一下执行过程,

1.首先,在main函数中定义了一个类,类的构造函数被执行

2.将类作为参数创建一个线程,这个期间线程复制了这个类对象,所以类的拷贝构造函数被执行

3.主线程被阻塞,子线程执行类中的operator函数

4.子线程执行完毕,子线程中复制的类对象进行析构

5.主线程继续执行,return0 main函数中的类对象被析构

这其中有一个问题就是类接受的参数是一个int类型的引用,而不是值(值参数传递和引用参数传递的区别),因而只能使用join()让主线程等待子线程执行。若使用detach(),当主线程执行完成之后,就收回了int参数的内存空间,而子线程可能还没有执行完成,还会调用这个int引用,就会出现引用参数内存空间被注销的错误。

所以要避免上述情况的发生,要不使用值作为参数,要不使用join让主线程等待子线程。

通过lambda函数创建一个线程

#include <iostream>
#include <thread>

using namespace std;

int main()
{
    //定义一个lambda函数
    auto mylambda = [] {
        cout << "lambda函数执行" << endl;
    };

    thread mthread(mylambda);
    mthread.join();

    cout << "我是主线程1!\n";
    return 0;
}

结果如下

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

葫芦娃找爷爷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值