C++并发与多线程-运行时选择线程数量

使用std::thread::hardware_concurrency() 来获得当前系统可以真正并发的线程数量,和cpu的核心数有关。

#include 
#include 
#include 
#include 
#include 
#include 

std::mutex g_lock;

template
struct accumulate_block {
	accumulate_block() {
		//std::cout << "创建一个线程: " << std::this_thread::get_id() << std::endl;
	}
	~accumulate_block() {
		std::lock_guard guard_lock(g_lock);
		std::cout << "销毁一个线程: " << std::this_thread::get_id() << std::endl;
	}
	inline void operator()(Iterator first, Iterator end, T& result) {
		result = std::accumulate(first, end, result);
	}
};

template
T parallel_accumulate(Iterator first, Iterator end, T init) {
	auto lenth = end - first;
	if (lenth <= 0)
		return init;
	unsigned long const count_per_thread = 25;
	unsigned long const max_threads = (lenth + count_per_thread - 1) / count_per_thread;
	unsigned long const hardware_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 = lenth / num_threads;
	
	std::vector results(num_threads);
	std::vector threads(num_threads - 1);
	Iterator block_begin = first;
	Iterator block_end = first;
	for (int i = 0; i < num_threads - 1; i++) {
		std::advance(block_end, block_size);
		threads[i] = std::thread(accumulate_block(), block_begin, block_end, std::ref(results[i]));
		block_begin = block_end;
	}
	accumulate_block()(block_end, end, std::ref(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);
}

int main()
{
    std::cout << "Hello World!\n"; 
	std::vector num_vec;
	for (int i = 0; i < 100; i++) {
		num_vec.push_back(i);
	}
	int result = 0;
	result = parallel_accumulate::iterator, int>(num_vec.begin(), num_vec.end(), result);
	std::cout << "最终计算得结果是: " << result << std::endl;
}

将求和函数使用多线程来实现,线程数量由逻辑线程数量和当前cpu核心数量的最小值决定。

运行结果:(5192是主线程的线程Id)

C++并发与多线程-运行时选择线程数量_第1张图片

你可能感兴趣的:(C++并发与多线程)