c++11 线程池+互斥量与原子操作性能对比

1.线程池

仿照boost::thread_group 实现std::thread_group:

#pragma once

#include <thread>
#include <mutex>
#include <list>
#include <memory>

namespace std
{
	//兼容boost::thread_group
	//使用std::thread代替boost::thread,std::mutex代替boost::shared_mutex
	class thread_group
	{
	private:
		thread_group(thread_group const&);
		thread_group& operator=(thread_group const&);
	public:
		thread_group() {}
		~thread_group()
		{
			for (auto it = threads.begin(), end = threads.end(); it != end; ++it)
			{
				delete *it;
			}
		}

		template<typename F>
		thread* create_thread(F threadfunc)
		{
			lock_guard<mutex> guard(m);
			auto_ptr<thread> new_thread(new thread(threadfunc));
			threads.push_back(new_thread.get());
			return new_thread.release();
		}

		void add_thread(thread* thrd)
		{
			if (thrd)
			{
				lock_guard<mutex> guard(m);
				threads.push_back(thrd);
			}
		}

		void remove_thread(thread* thrd)
		{
			lock_guard<mutex> guard(m);
			auto it = std::find(threads.begin(), threads.end(), thrd);
			if (it != threads.end())
			{
				threads.erase(it);
			}
		}

		void join_all()
		{
			lock_guard<mutex> guard(m);
			for (auto it = threads.begin(), end = threads.end(); it != end; ++it)
			{
				(*it)->join();
			}
		}

		size_t size() const
		{
			lock_guard<mutex> guard(m);
			return threads.size();
		}

	private:
		list<thread*> threads;
		mutable mutex m;
	};
}

2 三个版本的计数函数

#include "thread_group_zjd.h"

#include <atomic> 
#include <iostream>
#include <string>
#include <time.h>

using namespace std;
// 全局的结果数据 
long total = 0;

// 点击函数
void click_normal()
{
	for (int i = 0; i < 1000000; ++i)
	{
		// 对全局数据进行无锁访问 
		total++;
	}
}

atomic<long> total_atomic = 0;

// 点击函数
void click_atomic()
{
	for (int i = 0; i < 1000000; ++i)
	{
		// 对全局数据进行无锁访问 
		total_atomic++;
	}
}




// 对共享资源进行保护的互斥对象
mutex m;

void click_mutex()
{
	for (int i = 0; i < 1000000; ++i)
	{
		// 访问之前,锁定互斥对象
		std::lock_guard<mutex> lg(m);
// 		m.lock();
		total++;
		// 访问完成后,释放互斥对象 
// 		m.unlock();
	}
}

int thread_click(std::function<void()> _func)
{
	total = 0;
	total_atomic = 0;
	// 计时开始
	clock_t start = clock();
	// 创建100个线程模拟点击统计
	std::thread_group threads;
	for (int i = 0; i < 100; ++i)
	{
		threads.create_thread(_func);
	}

	threads.join_all();
	// 计时结束
	clock_t finish = clock();
	// 输出结果
	if (total_atomic)
	{
		cout << "result:" << total_atomic << endl;
	}
	else
	{
		cout << "result:" << total << endl;
	}
	cout << "duration:" << finish - start << "ms" << endl << endl;
	return 0;
}



int main(int argc, char* argv[])
{
	string s1;
	cout << "请输入,Please input Words(Normal, Mutex or Atomic, Quit to stop) "<<endl;

	while (true)
	{
		getline(cin, s1);

		if (s1 == "Normal")
		{
			thread_click(click_normal);
		}
		else if (s1 == "Mutex")
		{
			thread_click(click_mutex);
		}
		else if (s1 == "Atomic")
		{
			thread_click(click_atomic);
		}
		else if (s1 == "Quit")
		{
			break;
		}
		else
		{
			cout << "Input Error" << endl;
		}
	}
	

	return 0;
}

3 结果总结

Normal版本,多线程计算最快,但数值错误。

Mutex版本,计算耗时极高,数值正确。在c++11 Atomic之前需这样做。

Atomic版本,耗时有很大提升,数值正确。

 

BTW

使用lock_guard和m.lock的版本耗时有区别,下面截图为使用m.lock(),m.unlock()版本,速度略快;

 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值