Windows线程同步方法

本文介绍了线程同步的几种方法:互斥对象、事件对象及关键区。通过具体代码示例展示了如何利用这些机制来保证程序在同一时刻只有一个实例运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 1. 互斥
    利用互斥对象可以实现多个线程对某资源的互斥访问,互斥对象是内核对象,包含以下组成部分:一个线程ID(当前拥有该互斥对象的线程)、一个计数器(线程拥有互斥对象的次数)和一个使用计数。
    对于互斥对象的使用有一条原则:谁拥有谁释放。
   1)创建互斥对象
HANDLE CreateMutex{
   LPSECURITY_ATTRIBUTES lpMutexAttributes,    //Pointer to SECURITY_ATTRIBUTES, always NULL   
   BOOL bInitialOwner,                         //创建线程创建后是否拥有该互斥对象       
   LPCTSTR lpName                              //互斥对象名   
}       
   2)请求拥有互斥对象
DWORD WaitForSingleObject(
    HANDLE hHandle,                           //所请求对象的句柄
    DWORD dwMilliseconds                      //等待时间
)
   3)释放拥有的互斥对象
BOOL ReleaseMutex(HANDLE hMutex)
   4)利用互斥对象保证应用程序同一时刻只有一个实例运行
void main(){
    singleMutex = CreateMutex(NULL, TRUE, "single");
    if(singleMutex){
        if(GetLastError() == ERROR_ALREADY_EXISTS){
            输出:程序已经有一个实例在运行!
            return;
        }
    }
}

2.Event
   事件内核对象包含:使用计数,自动重置还是人工重置,状态。
   对于人工重置事件当某等待此事件的线程变为可调度后不会把该事件从有信号状态设为无信号状态,所以对于人工重置事件应在被保护代码前调用ResetEvent将事件设为无信号状态,在被保护代码后调用SetEvent将事件设为有信号状态。
   对于自动重置事件当等待该事件的线程中有一个变为可调度时OS会自动将该事件设为无信号状态,所以在自动重置事件所保护的代码后应调用SetEvent将事件设为有信号状态。
   1)创建事件对象
HANDLE CreateEvent(
    LPSECURITY_ATTRIBUTES lpEventAttributes,
    BOOL bManualReset,
    BOOL bInitialState,
    LPCTSTR lpName
)
   2)将事件对象设为有信号、无信号状态
BOOL SetEvent(HANDLE hEvent)
BOOL ResetEvent(HANDLE hEvent)
   4)利用事件对象保证应用程序同一时刻只有一个实例运行
void main(){
    HANDLE sigleEvent = CreateEvent(NULL, FALSE, FALSE, "single");
    if(sigleEvent ){
        if(GetLastError() == ERROR_ALREADY_EXISTS){
            输出:程序已经有一个实例在运行!
            return;
        }
    }
}
   为了实现线程间同步就使用自动重置事件,因为线程在ResetEvent执行前有可能被抢占。

3.关键区
   关键区是线程中访问共享资源的代码段。

   1)创建关键区
void InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
   2)访问关键区
void EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
   3)离开关键区
void LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
   4)释放关键区
void DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection)

4.总结
   利用内核对象(互斥对象和事件对象)完成线程同步速度慢,但可以在多个进程的各个线程间同步;
   关键区工作在用户态,速度较快但容易产生死锁。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值