- C++11 std::thread 标准库函数,跨平台;使用方便
- _beginthreadex 相对createThread 安全;与std::thread 性能基本持平(VS2013测试);使用上_beginthreadex 与createThread基本一样而std::thread 使用相对方便;
- C++11 std::mutex 与 CriticalSection 的对比;
- 如果是进程内部,建议使用临界区进行同步操作;VS2013测试结果,互斥量是临界区耗时的200倍左右;
- 两者的差距可能是因为:临界区是用户态,它变成内核态的是时间相对较少;而互斥量是内核对象,它每次竞争锁时都会进行用户态与内核态切换,相对比较耗时
测试代码如下:
// ThreadTest.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <atomic>
#include <mutex>
#include <thread>
#include <windows.h>
#include <iostream>
#include <process.h>
#include <time.h>
#include <list>
using namespace std;
#define MAX_THREADS 16
#define COUNT 100000
long total1 = 0;
long total2 = 0;
long total3 = 0;
std::mutex m_lock1;
CRITICAL_SECTION m_lock2;
CRITICAL_SECTION m_lock3;
#define BUF_SIZE 255
void use_std_mutex();
void use_win_critical();
void use_win_thread();
void test_mutex()
{
for (int i = 0; i < COUNT; i++)
{
m_lock1.lock();
total1 += 1;
m_lock1.unlock();
}
}
void test_critical()
{
for (int i = 0; i < COUNT; i++)
{
EnterCriticalSection(&m_lock2);
total2 += 1;
LeaveCriticalSection(&m_lock2);
}
}
unsigned __stdcall MyThreadFun(LPVOID lpParam)
{
for (int i = 0; i < COUNT; ++i)
{
EnterCriticalSection(&m_lock3);
total3 += 1;
LeaveCriticalSection(&m_lock3);
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
use_win_critical();
use_std_mutex();
use_win_thread();
system("pause");
return 0;
}
void use_std_mutex()
{
std::list<std::thread*> threadlist;
printf("test C++11 mutex cost time..\n");
clock_t start = clock();
for (int i = 0; i < MAX_THREADS; ++i)
{
std::thread *t1 = new std::thread((&test_mutex));
threadlist.push_back(t1);
}
for (auto it = threadlist.begin(); it != threadlist.end(); it++)
{
(*it)->join();
}
clock_t end = clock();
printf("result: %d \n", total1);
printf("cost: %dms\n", end - start);
for (auto it = threadlist.begin(); it != threadlist.end(); it++)
{
delete(*it);
}
}
void use_win_critical()
{
InitializeCriticalSectionAndSpinCount(&m_lock2, 2000);
std::list<std::thread*> threadlist;
printf("test windows API CriticalSection cost time..\n");
clock_t start = clock();
for (int i = 0; i < MAX_THREADS; ++i)
{
std::thread *t1 = new std::thread((&test_critical));
threadlist.push_back(t1);
}
for (auto it = threadlist.begin(); it != threadlist.end(); it++)
{
(*it)->join();
}
clock_t end = clock();
printf("result: %d \n", total2);
printf("cost: %dms\n", end - start);
for (auto it = threadlist.begin(); it != threadlist.end(); it++)
{
delete(*it);
}
}
void use_win_thread()
{
DWORD dwThreadIdArray[MAX_THREADS];
HANDLE hThreadArray[MAX_THREADS];
InitializeCriticalSection(&m_lock3);
printf("testing windows API ...\n");
clock_t start = clock();
for (int i = 0; i < MAX_THREADS; i++)
{
hThreadArray[i] = (HANDLE)_beginthreadex(
NULL,
0,
MyThreadFun,
NULL,
0,
NULL);
}
WaitForMultipleObjects(MAX_THREADS, hThreadArray, TRUE, INFINITE);
clock_t finish = clock();
printf("result:%d\n", total3);
printf("cost:%dms\n", finish - start);
for (int i = 0; i < MAX_THREADS; i++)
{
CloseHandle(hThreadArray[i]);
}
}
测试结果:
参考: