雕刻时光

just do it……nothing impossible
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

互斥量------线程间互斥

Posted on 2014-03-08 14:56  huhuuu  阅读(500)  评论(0编辑  收藏  举报

  互斥量的用途和临界区很像。它与临界区的差别在于可以跨线程使用,可以用来互斥进行多个线程间的数据访问,但是是以牺牲速度为代价的。只有临界区是非核心对象,那么互斥量就是一个核心对象了。核心对象的特点是有所谓的引用计数。所著一个未被拥有的互斥量,比锁住一个未被拥有的临界区需要花费几乎100倍的时间(数据引用自《Visual C++ 6.0编程学习捷径》)。

 

#include<stdio.h>
#include<process.h>
#include<windows.h>

volatile  long g_nLoginCount;
const int THREAD_NUM = 10;
volatile  long g_num;

CRITICAL_SECTION g_thread;
HANDLE g_Mutex;

unsigned int __stdcall ThreadFun(void *pPM){
    int thread_id=*((int *)pPM);
    
    Sleep(50);
    
    WaitForSingleObject(g_Mutex,INFINITE);
//    EnterCriticalSection(&g_thread);
    g_num++;
    Sleep(0);
    printf("ID : %d  全局:%d\n",thread_id,g_num);
//    LeaveCriticalSection(&g_thread);
    
    ReleaseMutex(&g_Mutex);
    return 0;
}

int main(){

    InitializeCriticalSection(&g_thread);
    g_Mutex = CreateMutex(NULL,FALSE,NULL);
    g_nLoginCount = 0;
    g_num=0;

    HANDLE handle[THREAD_NUM];

    int num=20;

    g_nLoginCount = 0;
    for(int i = 0;i < THREAD_NUM; i++){
        handle[i] = (HANDLE)_beginthreadex(NULL,0,ThreadFun,&i,0,NULL);
    }

    WaitForMultipleObjects(THREAD_NUM,handle,TRUE,INFINITE);

    CloseHandle(g_Mutex);
    DeleteCriticalSection(&g_thread);
    return 0;
}

结果:

这样也能达到关键段的效果,但互斥量比关键段有更多的优点:

1、互斥量常用与多进程间多线程的互斥,关键段只用于进程内多线程的互斥。

2、互斥量可以处理“遗弃问题”,即其他进程中某个线程因为一些原因挂了的话,系统检测到该线程占用互斥量,就会把该互斥量释放掉,以免其他线程一直等待下去。

 

最后总结下互斥量Mutex

1.互斥量是内核对象,它与关键段都有“线程所有权”所以不能用于线程的同步。

2.互斥量能够用于多个进程之间线程互斥问题,并且能完美的解决某进程意外终止所造成的“遗弃”问题。

 

参考:http://blog.csdn.net/morewindows/article/details/7470936,http://liuviphui.blog.163.com/blog/static/2022730842013363138649/