关键段 死锁 读写锁 事件 互斥量 信号量

 关键段结构typedef struct _RTL_CRITICAL_SECTION { PRTL_CRITICAL_SECTION_DEBUGDebugInfo; LONG LockCount; LONG RecursionCount; HANDLE OwningThread; // 这个最关键,理解了这个变量就理解了关键段 HAND...
摘要由CSDN通过智能技术生成

 

关键段结构

typedef struct _RTL_CRITICAL_SECTION {

    PRTL_CRITICAL_SECTION_DEBUGDebugInfo;

    LONG LockCount;

    LONG RecursionCount;

    HANDLE OwningThread; //  这个最关键,理解了这个变量就理解了关键段

    HANDLE LockSemaphore;

    DWORD SpinCount;

} RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;

 

关键段中有个线程所有权的概念,

简单来说就是调用 EnterCriticalSection 的线程, 自身必须调用 LeaveCriticalSection 才会释放. Enter 与Leave 要配对使用.

如若在别的线程调用 LeaveCriticalSection 是无效的; 

同时需要注意 EnterCriticalSection 可以在同一线程中调用 RecursionCount 次 , 那么 LeaveCriticalSection 也需要调用相同次数.

否则死锁;

注意:

           关键段与读写锁 都是用于线程间的互斥, 但无法用于线程同步 , 线程同步需要用到内核对象,比如event对象.

           比如关键段只能在同一线程中使用Enter , Leave. 而无法在一个线程中使用Enter , 另一个使用Leave;

 

 

代码说明:

int g_count = 0;

//2个关键段
CRITICAL_SECTION cs_lock_param,cs_lock_thread;

unsigned int WINAPI t1( void* lpParameter)
{
    // 应在同一线程中调用 Enter , Leave
    EnterCriticalSection(&cs_lock_param); 
    int param  = *(int*)lpParameter;
    LeaveCriticalSection(&cs_lock_param);

    EnterCriticalSection(&cs_lock_thread);
//    EnterCriticalSection(&cs_lock_thread); 此处取消注释将死锁.Enter , Leave 注意配对使用
    g_count++;
    cout <<"tid:" << GetCurrentThreadId() << "," <<g_count  << "," << param<< endl;
    LeaveCriticalSection(&cs_lock_thread);
    return 0;
}

int main()
{
     /*
         初始化关键段, 也可以使用InitializeCriticalSection
         InitializeCriticalSectionAndSpinCount 在多核处理器上或许速度更快些,使用旋转锁
         先循环尝试进入,如果超时, 则切换成内核等待状态
     */
    InitializeCriticalSectionAndSpinCount(&cs_lock_param,4000); // 4000 是循环次数.
    InitializeCriticalSectionAndSpinCount(&cs_lock_thread,4000);


    HANDLE handles[5];
    for(int i = 0; i < 5; ++i) {
        /*
            注意不能在这里EnterCriticalSection;
            即在另一个线程中 Leave 是无效的
        */
        //EnterCriticalSection(&cs_lock_param); 
        handles[i] = (HANDLE)_beginthreadex(NULL,0,t1,&i,0,NULL);
    }

    WaitForMultipleObjects(5,handles,TRUE,INFINITE);

    DeleteCriticalSection(&cs_lock_param);
    DeleteCriticalSection(&cs_lock_thread);
    for(int i = 0; i < 5 ; ++i)
        CloseHandle(handles[i]);
return 0;
}

 

 

 

读写锁:

读锁: 多个线程可同时访问.

          AcquireSRWLockShared 可同时进入.

          对应的读线程很适合用于读取共享资源

写锁:与关键段类似,如果愿意, 你也可以把关键段替换成 写锁 ,

<
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值