admin管理员组

文章数量:1567915

std::mutex 标准库的互斥锁;CRITICAL_SECTION Windows提供的临界区;QMutex Qt提供的互斥锁封装,显然,Qt封装的效率一般不如前两者。

参照这篇文章:https://www.iteye/blog/aigo-1908084

和他的结论差不多:在旧版本编译器上(如VS2012/2013),std::mutex 比临界区更慢;在新版本编译器上(如VS2015/2017),std::mutex 的效率显著提高,特别在竞争情况下比临界区快多了。

下面是 VS2013 和 VS2017 的运行截图(x86 Release):

测试代码两份:

#include <iostream>
#include <ctime>
#include <mutex>  
#include <atomic>    
#include <thread>  
#include <list>  
#include <functional>
#include <Windows.h>  

//表示被锁定的资源,每次加1  
long total = 0;

//win临界区
//Windows下的Mutex和​CRITICAL_SECTION,都是递归锁,
//而Linux下的pthread_mutex,默认是非递归锁
CRITICAL_SECTION critical;
//互斥锁
std::mutex mtx;
//可递归互斥锁
std::recursive_mutex r_mtx;

void run_critical(int count)
{
	for (int i = 0; i < count; ++i)
	{
		EnterCriticalSection(&critical);
		++total;
		LeaveCriticalSection(&critical);
	}
}

void run_mutex(int count)
{
	for (int i = 0; i < count; ++i)
	{
		//std::lock_guard<std::mutex> guard(mtx);
		mtx.lock();
		++total;
		mtx.unlock();
	}
}

void run_recursive_mutex(int count)
{
	for (int i = 0; i < count; ++i)
	{
		//std::lock_guard<std::recursive_mutex> guard(r_mtx);
		r_mtx.lock();
		++total;
		r_mtx.unlock();
	}
}

void run_test(std::function<void()> func, int thread_count, const char * type)
{
	std::list<std::thread*> threadlist;

	total = 0;
	clock_t start = clock();
	for (int i = 0; i < thread_count; ++i)
	{
		std::thread *t1 = new std::thread(func);
		threadlist.push_back(t1);
	}
	for (std::list<std::thread*>::const_iterator i = threadlist.begin(); i != threadlist.end(); i++)
	{
		(*i)->join();
	}
	clock_t finish = clock();
	std::cout << std::endl << type;
	std::cout << std::endl << "thread count:" << thread_count;
	std::cout << std::endl << "run count:" << total;
	std::cout << std::endl << "ms elapsed:" << finish - start << std::endl;

	for (std::list<std::thread*>::const_iterator i = threadlist.begin(); i != threadlist.end(); i++)
	{
		delete(*i);
	}
}

int main(int argc, char* argv[])
{
	InitializeCriticalSection(&critical);

	const int thread_count = 4;
	const int loop_count = 1000000;

	run_test(std::bind(&run_critical, loop_count), thread_count, "CRITICAL_SECTION");
	run_test(std::bind(&run_mutex, loop_count), thread_count, "std::mutex");
	run_test(std::bind(&run_recursive_mutex, loop_count), thread_count, "std::recursive_mutex");

	DeleteCriticalSection(&critical);
	system("pause");
	return 0;
}

#include <QCoreApplication>
#include <QMutex>
#include <QReadWriteLock>
#include <QDebug>
#include <ctime>
#include <mutex>  
#include <atomic>    
#include <thread>  
#include <list>  
#include <functional>
#include <Windows.h>  

//表示被锁定的资源,每次加1  
long total = 0;

//win临界区
//Windows下的Mutex和​CRITICAL_SECTION,都是递归锁,
//而Linux下的pthread_mutex,默认是非递归锁
CRITICAL_SECTION critical;
//互斥锁
std::mutex mtx;
//可递归互斥锁
std::recursive_mutex r_mtx;
//qt互斥锁
QMutex qtx{ QMutex::NonRecursive };//默认就是非递归
//qt可递归互斥锁
QMutex r_qtx{ QMutex::Recursive };
//qt读写锁
QReadWriteLock qrw{ QReadWriteLock::NonRecursive };//默认就是非递归

void run_critical(int count)
{
	for (int i = 0; i < count; ++i)
	{
		EnterCriticalSection(&critical);
		++total;
		LeaveCriticalSection(&critical);
	}
}

void run_mutex(int count)
{
	for (int i = 0; i < count; ++i)
	{
		//std::lock_guard<std::mutex> guard(mtx);
		mtx.lock();
		++total;
		mtx.unlock();
	}
}

void run_recursive_mutex(int count)
{
	for (int i = 0; i < count; ++i)
	{
		//std::lock_guard<std::recursive_mutex> guard(r_mtx);
		r_mtx.lock();
		++total;
		r_mtx.unlock();
	}
}

void run_qmutex(int count)
{
	for (int i = 0; i < count; ++i)
	{
		qtx.lock();
		++total;
		qtx.unlock();
	}
}

void run_recursive_qmutex(int count)
{
	for (int i = 0; i < count; ++i)
	{
		r_qtx.lock();
		++total;
		r_qtx.unlock();
	}
}

void run_qreadwritelock_write(int count)
{
	for (int i = 0; i < count; ++i)
	{
		qrw.lockForWrite();
		++total;
		qrw.unlock();
	}
}

void run_qreadwritelock_read(int count)
{
	for (int i = 0; i < count; ++i)
	{
		qrw.lockForRead();
		++total;
		qrw.unlock();
	}
}

void run_test(std::function<void()> func, int thread_count, const char * type)
{
	std::list<std::thread*> threadlist;

	total = 0;
	clock_t start = clock();
	for (int i = 0; i < thread_count; ++i)
	{
		std::thread *t1 = new std::thread(func);
		threadlist.push_back(t1);
	}
	for (std::list<std::thread*>::const_iterator i = threadlist.begin(); i != threadlist.end(); i++)
	{
		(*i)->join();
	}
	clock_t finish = clock();
	qDebug() << "\n"<< type;
	qDebug() << "thread count:" << thread_count;
	qDebug() << "run count:" << total;
	qDebug() << "ms elapsed:" << finish - start;

	for (std::list<std::thread*>::const_iterator i = threadlist.begin(); i != threadlist.end(); i++)
	{
		delete(*i);
	}
}

int main(int argc, char* argv[])
{
	QCoreApplication app(argc, argv);
	InitializeCriticalSection(&critical);

	const int thread_count = 4;
	const int loop_count = 1000000;

	run_test(std::bind(&run_critical, loop_count), thread_count, "CRITICAL_SECTION");
	run_test(std::bind(&run_mutex, loop_count), thread_count, "std::mutex");
	run_test(std::bind(&run_recursive_mutex, loop_count), thread_count, "std::recursive_mutex");
	run_test(std::bind(&run_qmutex, loop_count), thread_count, "QMutex");
	run_test(std::bind(&run_recursive_qmutex, loop_count), thread_count, "QMutex(recursive)");
	run_test(std::bind(&run_qreadwritelock_write, loop_count), thread_count, "QReadWriteLock(write)");
	run_test(std::bind(&run_qreadwritelock_read, loop_count), thread_count, "QReadWriteLock(read)");

	DeleteCriticalSection(&critical);
	return app.exec();
}

 

本文标签: 效率测试stdampmutex