第八章 用户模式下的线程同步

时间:2021-01-18 23:33:44

(1)什么情况下线程之间需要通信

  • 多个线程同时访问一个共享资源,但是不能破坏资源的完整性
  • 线程需要通知其他线程任务已经完成

(2)原子访问,以及Interlocked系列函数.

  所谓原子访问(atomic access)就是一个线程在访问某个资源的同时能够保证没有其他线程会在同一时刻访问同一资源.

  

LONG InterLockedExchangeAdd(PLONG  volatile plAddend,LONG lIncrement)

LONGLONG  InterLockedExchangeAdd64(PLONGLONG   volatile plAddend,LONGLONG  lIncrement)

LONG InterlockedExchange64(PLONG volatile plTarget ,PLONG  value )

LONGLONG  InterlockedExchange(PLONGLONG  volatile plTarget ,PLONGLONG   value )

(3)临界区(关键段)ctritical session 

CRITICAL_SECTION g_cs;
InitializeCriticalSection(&g_cs);
//线程函数中
void ThreadTmp1()
{
  EnterCriticalSection(&g_cs);
  //...
   // 离开临界区
   LeaveCriticalSection(&g_cs);
   //TryEnterCriticalSection(&g_cs); 当公共资源未被访问时返回ture 需要调用 LeaveCriticalSection
  } 
 
  DeleteCriticalSection(&g_cs);
(3)关于旋转锁
  当线程访问的资源被占用,会由用户模式进入内核模式而占用一定的时间.配有多处理器的机器上,当前占有的资源可能在另一个线程上面运行,而且可能很快就会结束对资源的访问,也许在进入内核模式之前,已经被占用的资源已经被释放,这样就会浪费很多的cpu时间.
  所以可以调用EnterCriticalSection的时候使用旋转锁
BOOL IntitializeCriticalSectionAndSpinCount{ //InitializeCriticalSection的作用也实现了
PCRITICAL_SECTION pcs, DWORD dwSpinCount //希望旋转的次数
}

BOOL SetCriticalSectionAndSpinCount{
PCRITICAL_SECTION pcs,
DWORD dwSpinCount //希望旋转的次数
}
建议使用临界区时使用IntitializeCriticalSectionAndSpinCount
(4)Slim 读/写锁
SWRLock sLock;

InitializeSWRLock (&sLock);

//写入者同步操作
VOID  AcquireSRWLockExclusive(PSWRLOCK &sLock)
VOID  ReleaseSRWLockExclusive(PSWRLOCK &sLock)

//读取者同步操作
VOID  AcquireSRWLockShared(PSWRLOCK &sLock)
VOID  ReleaseSRWLockShared(PSWRLOCK &sLock)

同步的性能比较

第八章 用户模式下的线程同步

(5)条件变量

  条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起;另一个线程使"条件成立"(给出条件成立信号)。也就是线程以原始方式把自己阻塞,等待某个条件的成立.

BOOL SleepConditionVariableCS()
{
    PCONDTION_VARIABLE pConditionVariable,//初始化的条件变量
    PCRITICAL_SESSION pCritialSession,  
    DWORD  dwMilliseconds,  
}

BOOL SleepConditionVariableSWR()
{
    PCONDTION_VARIABLE pConditionVariable,
    PSWRLOCK pSWRLock,  
    DWORD  dwMilliseconds,  
}

VOID WakeConditionVariable()//唤醒线程
{

  CONDTION_VARIABLE ConditionVariable,
}

VOID WakeAllConditionVariable()
{

  CONDTION_VARIABLE ConditionVariable,
 
 
}