c++11并发编程历程(3)异常环境下的等待

在c++11并发编程历程(2)中我分享了在非异常的情况下调用join(),本文来看一下在异常环境下调用join
()进行等待
话不多说,上代码

#include <iostream>
#include <thread>

using namespace std;

struct func
{
	int &m_i;
	func(int &i) :m_i(i) {}
	void operator()()
	{
		for (int i = 0; i < 1000; ++i)
		{
			int addr = m_i++;
			cout << addr << endl;
		}
	}
};

void f()
{
	int a = 0;
	func my_func(a);
	thread my_thread(my_func);
	try {
		int a = 0;
		throw -1;
		int b = 1 / a;
	}
	catch (int)
	{
		if (my_thread.joinable())
		{
			my_thread.join();
			cout << "异常退出,等待新线程正常结束" << endl;
		}		
	}
}

int main()
{
	f();
}

关于其中看不懂的语法点,可以参考博主的c++11专栏和c++专栏文章
运行结果部分截图如下:

在这里插入图片描述

从上面代码中可以看到,我们在异常情况下也会去等待新线程运行结束,看似好像能解决问题,但是存在问题也很多,代码啰嗦,作用域混乱。
下面介绍一个简单清晰的机制,RAII(百度百科称为“资源获取就是初始化”),并提供一个类,在它的析构函数中使用join();

#include <iostream>
#include <thread>

using namespace std;

struct func
{
	int &m_i;
	func(int &i) :m_i(i) {}
	void operator()()
	{
		for (int i = 0; i < 1000; ++i)
		{
			int addr = m_i++;
			cout << addr << endl;
		}
	}
};


class thread_man
{
public:
	explicit thread_man(thread &my_thread) :m_thread(my_thread) {}
	~thread_man()
	{
		if (m_thread.joinable())
		{
			m_thread.join();
			cout << "join end" << endl;
		}
	}
private:
	thread &m_thread;
};

void f()
{
	int a = 0;
	func my_func(a);
	thread my_thread(my_func);
	thread_man my_thread_man(my_thread);
}

int main()
{
	f();
}

运行结果如下:
在这里插入图片描述
这种写法巧妙之处在于因为函数f结束的时候需要按照构造顺序反序销毁,例中f函数执行到最后一行完会反向先销毁my_thread_man,而销毁类对象my_thread_man需要调用析构函数,析构函数中会检测新线程是否执行完成,若无,则等待新线程执行完成后析构类对象my_thread_man

人,总是要有一点精神的,不是吗

发布了32 篇原创文章 · 获赞 23 · 访问量 872

猜你喜欢

转载自blog.csdn.net/weixin_40179091/article/details/105241316