Effective C++: std::thread

线程不同于普通的local variable.即使一个跑在函数中的线程,如果该函数由于if-elseif, return或者其他原因而提前结束了那么该函数内的变量遵循RAII原则,自动销毁,然而线程则不会,仍然就继续执行下去

我们来首先看一个例子:

#include <iostream>
#include <thread>
#include <vector>

constexpr unsigned long tenMillion = 10000000;

bool doWork(std::function<bool(const int&)> filter, const unsigned long& maxVal = tenMillion)
{
	std::vector<int> vec;

	std::function<bool()> conditionsAreSatisfied = [&vec]()->bool { return false; };

	std::thread t([&filter, maxVal, &vec]() { for (unsigned long i = 0; i <= maxVal; ++i) { if (filter(i)) vec.push_back(i); }});

	if (conditonsAreSatisfied()) { //注意前面我们设置了conditionsAreSatisfied()返回false.
		thread.get().join();
		return true;
	}else { //由于返回的是false,因此该线程并没有被join()也没有被detach().
		return false;
	}
}

int main()
{
	doWork([](const int& number)->bool { return (number % 2 == 0) ? true : false;});

	return 0;
}

有时候我们可能在一个函数里面可能会用if-elseif产生很多分支每种分支对应的情况也不一样。

这就造成了我们可能没有对当前函数的的std::thread执行join(),然后就结束了函数的生命周期(lifetime),这么一来我们跑在该函数的线程如果是以引用的形式使用了当前函数内的local variable,很显然就会造成terminal咯.

肯定是有解决办法的我们再来看一个例子:

#include <iostream>
#include <thread>
#include <vector>

class ThreadRAII {
public:
	enum class Action : int {join, detach};

	ThreadRAII(std::thread&& t, ThreadRAII::Action act);
	~ThreadRAII();

	std::thread& get();

private:
	Action action;
	std::thread thread;
};

ThreadRAII::ThreadRAII(std::thread&& t, ThreadRAII::Action act)
	:thread(std::move(t)),
	action(act)
{
	//
}

std::thread& ThreadRAII::get()
{
	return (this->thread);
}

ThreadRAII::~ThreadRAII()
{
	if (thread.joinable()) {
		if (this->action == Action::join) {
			(this->thread).join();

		}else{
			(this->thread).detach();
		}
	}
}

constexpr unsigned long tenMillion = 10000000;

bool doWork(std::function<bool(const int&)> filter, const unsigned long& maxVal = tenMillion)
{
	std::vector<int> vec;

	std::function<bool()> conditionsAreSatisfied = [&vec]()->bool { return false; };

	//std::thread t([&filter, maxVal, &vec]() { for (unsigned long i = 0; i <= maxVal; ++i) { if (filter(i)) vec.push_back(i); }});
	ThreadRAII thread(std::thread([&filter, maxVal, &vec]() { for (unsigned long i = 0; i <= maxVal; ++i) { if (filter(i)) vec.push_back(i); }}), ThreadRAII::Action::join);

	if (false) { //注意这里的false.
		thread.get().join();
		return true;
	}else { //在return之前ThreadRAII的析构函数被调用,这样即使前面没有对thread进行jion(),在ThreadRAII的析                      //构函数里面也会调用jion()的
		return false;
	}
}

int main()
{
	doWork([](const int& number)->bool { return (number % 2 == 0) ? true : false;});

	return 0;
}

 

转载于:https://my.oschina.net/SHIHUAMarryMe/blog/683101

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值