1.3. C++併發(轉移線程所有權,簡單控制線程數量)

std::thread實例是可以轉移的,但是不能複製,因此轉移線程的所有權也是很重要的內容點。
案列1:轉移線程所有權並且使用類進行線程管理(RAII)
該實例類比前面1.2中提到的thread_guard類不同之處在於管理類不是引用thread實例而是將thread實例所有權轉移到了類中。

#include <thread>
class scoped_thread
{
	std::thread t:
public:
	explicit scoped_thread(std::thread t_):
		t(std::move(t_))
	{
		if(!t.joinable())
			throw std::logic_error("No thread");
	}
	~scoped_thread()
	{
		t.join();
	}
	scoped_thread(scoped_thread const&)=delete;
	scoped_thread& operator=(scoped_thread const&)=delete;
};
struct func;
int main()
{
	int some_local_state=1;
	scoped_thread t(std::thread(func(some_local_state)));
	do_something();
	return 0;
}

實例2:簡單控制線程數量
使用std::vectorstd::thread是線程邁向自動化管理的第一步

template<typename Iterator, typename T>
struct accumulate_block
{
	void operator()(Iterator first, Iterator last, T& result)
	{
		result = std::accumulate(first, last, result);
	}
};
template<typename Iterator first, Iterator last, T init)
{
	unsigned long const length = std::distance(first, last);
	if(!length)
		return init;
	unsigned long const min_per_thread = 25;
	unsigned long const max_threads = (length+min_per_thread-1)/min_per_thread;
	unsigned long const hard_ware_threads = std::thread::hardware_concurrency();
	unsigned long const num_threads = std::min(hardware_threads!=0?hardware_threads:2,max_threads);
	unsigned long const block_size=length/num_threads;
	std::vector<T> results(num_threads);
	std::vector<std::thread> threads(num_threads-1);
	Iterator block_start=first;
	for(unsigned long i=0;i<(num_threads-1); ++i)
	{
		Iterator block_end = block_start;
		std::advance(block_end, block_size);
		thread[i]=std::thread(accumulate_block<Iterator, T>(), block_start, block_end, std::ref(results[i]));
		block_start = block_end;
	}
	accumulate_block<Iterator, T>()(block_start, last, results[num_threads-1]);
	std::for_each(threads.begin(), threads.end(), std::mem_fn(&std::thread::join));
	return std::accumulate(results.begin(), results.end(), init);
}

實例3:標識線程
用來區別線程,線程標識符都是std::thread::id類型,可以通過std::thread對象調用get_id()來獲得,或者調用std::this_thread::get_id()獲得。很多情況下,std::thread::id可以用來作爲線程的通用標識符

std::thread::id master_thread;
void some_core_part_of_algorithm()
{
	if(std::this_thread::get_id()==master_thread)
	{
		do_master_thread_work();
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章