多线程(c++11)------创建线程

        c++11 中创建线程非常简单:

#include <iostream>
#include <thread>
using namespace  std;

void thread_func()
{
	//...
}

void thread_func2(int i)
{
	// ...
}


int main(int argc, _TCHAR* argv[])
{
	thread t1{ thread_func };
	thread t2{ thread_func2, 5 };

	return 0;
}

        首先包含头文件<thread>,这是c++11中新添加的类。然后用函数名和参数来构造一个thread对象就可以了。构造完成后线程会自动执行。下面是构造函数的参数形势:

template<class _Fn,
		class... _Args>
		explicit thread(_Fn&& _Fx, _Args&&... _Ax)

        第一个参数是一个函数,后面是一个可变长参数表。


        除了创建线程,一般还会有几个相配套的控制线程的系统函数。

                1、Join函数

                2、Detach函数


在vs2013中编译运行上面的测试代码,发现会发生运行时错误!为什么呢?

        因为在多线程情况下,无论子线程执行完毕与否,一旦主线程执行完毕退出,所有子线程执行都会终止。这时整个进程结束或僵死(部分线程保持一种终止执行但还未销毁的状态,而进程必须在其所有线程销毁后销毁,这时进程处于僵死状态),在第一个例子的输出中,可以看到子线程还来不及执行完毕,主线程的main()函数就已经执行完毕,从而所有子线程终止。需要强调的是,线程函数执行完毕退出,或以其他非常方式终止,线程进入终止态,但千万要记住的是,进入终止态后,为线程分配的系统资源并不一定已经释放,而且可能在系统重启之前,一直都不能释放。终止态的线程,仍旧作为一个线程实体存在与操作系统中。(这点在win和unix中是一致的。)而什么时候销毁线程,取决于线程属性。

         通常,这种终止方式并非我们所期望的结果,而且一个潜在的问题是未执行完就终止的子线程,除了作为线程实体占用系统资源之外,其线程函数所拥有的资源(申请的动态内存,打开的文件,打开的网络端口等)也不一定能释放。所以,针对这个问题,主线程和子线程之间通常定义两种关系:
        1、可会合(joinable)。这种关系下,主线程需要明确执行等待操作。在子线程结束后,主线程的等待操作执行完毕,子线程和主线程会合。这时主线程继续执行等待操作之后的下一步操作。主线程必须会合可会合的子线程,Thread类中,这个操作通过在主线程的线程函数内部调用子线程对象的jion()函数实现。必须强调的是,即使子线程能够在主线程之前执行完毕,进入终止态,也必需显示执行会合操作,否则,系统永远不会主动销毁线程,分配给该线程的系统资源(线程id或句柄,线程管理相关的系统资源)也永远不会释放。
        2、相分离(detached)。顾名思义,这表示子线程无需和主线程会合,也就是相分离的。这种情况下,子线程一旦进入终止态,系统立即销毁线程,回收资源。无需在主线程内调用wait()实现会合。Thread类中,调用detach()使线程进入detached状态。这种方式常用在线程数较多的情况,有时让主线程逐个等待子线程结束,或者让主线程安排每个子线程结束的等待顺序,是很困难或者不可能的。所以在并发子线程较多的情况下,这种方式也会经常使用。

        缺省情况下,创建的线程都是可会合的。可会合的线程可以通过调用detach()方法变成相分离的线程。但反向则不行。


        我们的主线程中既没有调用jion函数来等待子线程结束,也没用调用detach来将其交给操作系统管理。最终很可能导致进程僵死,资源无法释放!c++11对这种情况视为不合法,出现这种情况,c++11就会调用terminate函数来终止我们的进程。而在vs中调用terminate函数就会出现运行时错误对话框!


        所以,要记住:对于每一个子线程,到么就调用join,要么就调用detach。否则存在安全隐患,视为不合法!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值