window下线程同步之(原子锁)

原子锁:当多个线程同时对同一资源进行操作时,由于线程间资源的抢占,会导致操作的结果丢失或者不是我们预期的结果。

比如:线程A对一个变量进行var++操作,线程B也执行var++操作,当线程A执行var++时,如果线程切换时间恰好是线程A将结果存在var变量之前,那么线程B继续执行var++;此时假设var值已经被线程B更新,这时轮流到线程A执行,线程A会将接着上次停止的点继续向下执行,这时B对var变量的更改将会被覆盖掉;原子锁是对单条操作指令进行原子保护,保证在同一时间,只能有一个线程对变量进行操作,以此确保数据的正确性.

1、InterlockedIncrement:加1操作; 
2、InterlockedDecrement:减1操作; 
3、InterlockedExchangeAdd:加上“指定”的值,可以加上一个负数; 
4、InterlockedExchange、InterlockedExchangePointer:能够以原子操作的方式用第二个参数的值来取代第一个参数的值;

一般情况下,在多线程编程中如果对某一个变量的值进行改变的话,使用以上互锁函数确实比较方便,但有很多时候多线程间会操作更为复杂的东西
比如对一个结构的赋值、对链表的插入与删除 等等,以上互锁函数不能满足要求,所以要使用更为高级的多线程间的同步技术!

没有使用原子锁的情况:
#include <Windows.h> 
#include <iostream> 
using namespace std;

#define ThreadNum  2 
#define CIRCLETIME 1000000 
long g_loginCount = 0; 
long g_value = 0;

DWORD WINAPI ThreadProc1( __in  LPVOID lpParameter ) 
{ 
    for( int index=0; index<CIRCLETIME; index++ ) 
    { 
        g_loginCount++; 
    } 
    return 0; 
}

DWORD WINAPI ThreadProc2( __in  LPVOID lpParameter ) 
{ 
    for( int index=0; index<CIRCLETIME; index++ ) 
    { 
        g_loginCount++; 
    } 
    return 0; 
}

int main() 
{ 
    HANDLE handle[ ThreadNum ] = {0};

    handle[0] = CreateThread(NULL,0,ThreadProc1,NULL,0,NULL); 
    handle[1] = CreateThread(NULL,0,ThreadProc2, NULL,0 ,NULL );

    WaitForMultipleObjects(ThreadNum,handle,TRUE,INFINITE); 
    CloseHandle( handle[0] ); 
    CloseHandle( handle[1] );

    cout << "循环之后的值为: " << g_loginCount  << " " <<  g_value << endl; 
    return 0; 
}

运行2次结果如下:
image

image

使用原子锁的情况:

DWORD WINAPI ThreadProc2( __in  LPVOID lpParameter ) 
{ 
    for( int index=0; index<CIRCLETIME; index++ ) 
    { 
        g_loginCount++; 
        InterlockedIncrement( &g_value  ); 
    } 
    return 0; 
}

DWORD WINAPI ThreadProc1( __in  LPVOID lpParameter ) 
{ 
    for( int index=0; index<CIRCLETIME; index++ ) 
    { 
        g_loginCount++; 
        InterlockedIncrement( &g_value  ); 
    }         
    return 0; 
}

 

运行2次结果如下:

image
image

posted @ 2014-04-14 15:47  执迷不悟~  阅读(2940)  评论(0编辑  收藏  举报