多线程同步之WIN API互锁函数 (可以避免使用CriticalSection或Mutex)
一 互锁函数
互锁函数的家族十分的庞大,可以查看msdn(http://msdn2.microsoft.com/en-us/library/ms686360.aspx)以InterLocked开始的函数都是户数函数。使用互锁函数的优点是:他的速度要比其他的CriticalSection,Mutex,Event,Semaphore快很多。
二 简单实例
使用一些实例说明部分互锁函数的使用:
1) LONG InterlockedExchangeAdd( PLONG plAddend,LONG Increment);
简单实例,在线程函数中对全局的变量自增,在开始使其为0,在线程都执行完以后输出全局变量的值,如果我们不使用互锁函数,则最后输出的结果,大部分情况是不正确的,比如我们一共有10000个线程的话,则全局变量的值一般是比10000要小;但是如果我们使用互锁函数来实现自增,则就快速的实现了线程安全,最后输出的全局变量一定是10000.
#include <windows.h>
#include <process.h>
#include <stdio.h>
#define THREAD_MAX 100000
int g_x = 0;
unsigned __stdcall ThreadEntity(void * pVoid)
{
g_x++;
//InterlockedExchangeAdd(reinterpret_cast<long*>(&g_x),1);
return 1;
}
int main()
{
HANDLE hth[THREAD_MAX];
unsigned uiThreadID[THREAD_MAX];
printf("start create children threadings:/n");
for(int i = 0; i < THREAD_MAX; ++i)
{
hth[i] = (HANDLE)_beginthreadex( NULL, // security
0, // stack size
ThreadEntity,
(void*)&i, // arg list
0,
&uiThreadID[i] );
if ( hth[i]== 0 )
printf("Failed to create thread 1/n");
}
WaitForMultipleObjects( THREAD_MAX, hth,true,10000);
for(int i = 0; i<THREAD_MAX; ++i)
CloseHandle( hth[i] );
printf("last: g_x is %d/n",g_x);
printf("Primary thread terminating./n");
}
在上面的代码中使用了 //InterlockedExchangeAdd(reinterpret_cast<long*>(&g_x),1); 来实现g_x的线程安全的自增。
2)使用LONG InterlockedExchange(PLONG plTarget,LONG lValue);实现循环锁:
// Global variable indicating whether a shared resource is in use or not
BOOL g_fResourceInUse = FALSE;
void Func1()
{
//Wait to access the resource.
while(InterlockedExchange(&g_fResourceInUse, TRUE) == TRUE)
Sleep(0);
//Access the resource.
//We no longer need to access the resource.
InterlockedExchange(&g_fResourceInUse, FALSE);
}
3)太多了,不举了,以后用到了再放到这里把。
一 互锁函数
互锁函数的家族十分的庞大,可以查看msdn(http://msdn2.microsoft.com/en-us/library/ms686360.aspx)以InterLocked开始的函数都是户数函数。使用互锁函数的优点是:他的速度要比其他的CriticalSection,Mutex,Event,Semaphore快很多。
二 简单实例
使用一些实例说明部分互锁函数的使用:
1) LONG InterlockedExchangeAdd( PLONG plAddend,LONG Increment);
简单实例,在线程函数中对全局的变量自增,在开始使其为0,在线程都执行完以后输出全局变量的值,如果我们不使用互锁函数,则最后输出的结果,大部分情况是不正确的,比如我们一共有10000个线程的话,则全局变量的值一般是比10000要小;但是如果我们使用互锁函数来实现自增,则就快速的实现了线程安全,最后输出的全局变量一定是10000.
#include <windows.h>
#include <process.h>
#include <stdio.h>
#define THREAD_MAX 100000
int g_x = 0;
unsigned __stdcall ThreadEntity(void * pVoid)
{
g_x++;
//InterlockedExchangeAdd(reinterpret_cast<long*>(&g_x),1);
return 1;
}
int main()
{
HANDLE hth[THREAD_MAX];
unsigned uiThreadID[THREAD_MAX];
printf("start create children threadings:/n");
for(int i = 0; i < THREAD_MAX; ++i)
{
hth[i] = (HANDLE)_beginthreadex( NULL, // security
0, // stack size
ThreadEntity,
(void*)&i, // arg list
0,
&uiThreadID[i] );
if ( hth[i]== 0 )
printf("Failed to create thread 1/n");
}
WaitForMultipleObjects( THREAD_MAX, hth,true,10000);
for(int i = 0; i<THREAD_MAX; ++i)
CloseHandle( hth[i] );
printf("last: g_x is %d/n",g_x);
printf("Primary thread terminating./n");
}
在上面的代码中使用了 //InterlockedExchangeAdd(reinterpret_cast<long*>(&g_x),1); 来实现g_x的线程安全的自增。
2)使用LONG InterlockedExchange(PLONG plTarget,LONG lValue);实现循环锁:
// Global variable indicating whether a shared resource is in use or not
BOOL g_fResourceInUse = FALSE;
void Func1()
{
//Wait to access the resource.
while(InterlockedExchange(&g_fResourceInUse, TRUE) == TRUE)
Sleep(0);
//Access the resource.
//We no longer need to access the resource.
InterlockedExchange(&g_fResourceInUse, FALSE);
}
3)太多了,不举了,以后用到了再放到这里把。