admin管理员组

文章数量:1530365

  1. C++11 std::thread 标准库函数,跨平台;使用方便
  2. _beginthreadex 相对createThread 安全;与std::thread 性能基本持平(VS2013测试);使用上_beginthreadex 与createThread基本一样而std::thread 使用相对方便;
  3. C++11 std::mutex 与 CriticalSection 的对比;
    1. 如果是进程内部,建议使用临界区进行同步操作;VS2013测试结果,互斥量是临界区耗时的200倍左右;
    2. 两者的差距可能是因为:临界区是用户态,它变成内核态的是时间相对较少;而互斥量是内核对象,它每次竞争锁时都会进行用户态与内核态切换,相对比较耗时

测试代码如下:

// 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]);
    }
}
测试结果:

参考:

1、http://aigo.iteye/blog/1908084

2、https://blog.csdn/huntzw/article/details/7001602

本文标签: 运行库threadWindowsstdbeginthreadex