1. 程式人生 > >c++執行緒併發:mutex,atomic,自旋鎖spinlock,單執行緒

c++執行緒併發:mutex,atomic,自旋鎖spinlock,單執行緒

自旋鎖直接呼叫了boost庫的#include <boost/smart_ptr/detail/spinlock.hpp>

測試執行緒併發的情況下耗時,不太明白為什麼boost的spinlock效率這麼低,還是說boost的spinlock是有其它專業用途...

在一個共有資源的情況下,
由於任務的簡單性,只是++,單執行緒最快
多執行緒無鎖次之,但是結果錯誤
atomic原子操作耗時稍長,但由於原子操作的關係,結果正確
mutex 效能損失比較大,為atomic的4倍左右,雖然保證了結果的正確性,但是耗時卻是原來的10多倍
boost spinlock效率墊底了,不太明白細節,等下研究一下
是鎖競爭的關係?還是核心態和使用者態切換的關係?
請明白的大神指點
不過有一點給自己提了個醒,在不瞭解鎖機制的情況下還是得慎用

下面是程式碼:

// BoostThread1.cpp : 定義控制檯應用程式的入口點。
//

#include "stdafx.h"
#include <boost/lambda/lambda.hpp>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <boost/thread/thread.hpp>
#include <boost/atomic.hpp>
#include <boost/smart_ptr/detail/spinlock.hpp>
#include "time.h"

//在一個共有資源的情況下,
//由於任務的簡單性,只是++,單執行緒最快
//多執行緒無鎖次之,但是結果錯誤
//atomic原子操作耗時稍長,但由於原子操作的關係,結果正確
//mutex 效能損失比較大,為atomic的4倍左右,雖然保證了結果的正確性,但是耗時卻是原來的10多倍
//boost spinlock效率墊底了,不太明白細節,等下研究一下
//是鎖競爭的關係?還是核心態和使用者態切換的關係?
//請明白的大神指點
//不過有一點給自己提了個醒,在不瞭解鎖機制的情況下還是得慎用

long total = 0;
boost::atomic_long total2(0);
boost::mutex m;
boost::detail::spinlock sp;

void thread_click()
{
	for (int i = 0; i < 10000000; ++i)
	{
		++total;
	}
}

void mutex_click()
{
	for (int i = 0; i < 10000000  ; ++i)
	{
		m.lock();
		++total;
		m.unlock();
	}
}

void atomic_click()
{
	for (int i = 0; i < 10000000; ++i)
	{
		++total2;
	}
}


void spinlock_click()
{
	for (int i = 0; i < 10000000; ++i)
	{
		boost::lock_guard<boost::detail::spinlock> lock(sp);
		++total;
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	int thnum = 100;
	clock_t start = clock();
	boost::thread_group threads;
	for (int i = 0; i < thnum;++i)
	{
		threads.create_thread(mutex_click);
	}
	threads.join_all();
	//計時結束
	clock_t end = clock();
	std::cout << "多執行緒mutex結果:" << total << std::endl;
	std::cout << "多執行緒mutex耗時:" << end - start << std::endl;
	total = 0;
	start = clock();
	for (int i = 0; i < thnum; ++i)
	{
		threads.create_thread(thread_click);
	}
	threads.join_all();
	end = clock();
	std::cout << "多執行緒無鎖結果:" << total << std::endl;
	std::cout << "多執行緒無鎖耗時:" << end - start << std::endl;

	total = 0;
	start = clock();
	for (int i = 0; i < thnum; ++i)
	{
		threads.create_thread(atomic_click);
	}
	threads.join_all();
	end = clock();
	std::cout << "多執行緒atomic結果:" << total2 << std::endl;
	std::cout << "多執行緒atomic耗時:" << end - start << std::endl;
	total = 0;
	start = clock();
	for (int i = 0; i < 10000000*thnum;i++)
	{
		++total;
	}
	end = clock();
	std::cout << "單執行緒結果:" << total << std::endl;
	std::cout << "單執行緒耗時:" << end - start << std::endl;

	total = 0;
	start = clock();
	for (int i = 0; i < thnum; ++i)
	{
		threads.create_thread(spinlock_click);
	}
	threads.join_all();
	end = clock();
	std::cout << "自旋鎖結果:" << total << std::endl;
	std::cout << "自旋鎖耗時:" << end - start << std::endl;
	getchar();
	return 0;
}


上圖

效能對比