线程同步控制

线程的重要特性就在于,如何让多个线程之间互相合作,而不是争吵罢工。

同步(synchronous):当程序1调用程序2时,程序1停下来不动,直到程序2完成回到程序1来,程序1才继续下去,那么两者的关系就是同步;

异步(asynchronous):如果程序1调用程序2时,经自继续自己的下一个动作,那么两者之间的关系就是异步;

win32中关于进程和线程的协调工作是由同步机制来完成。

临界区域:

所谓临界区域就是指用来处理一份被共享的资源的程序代码。

必须对临界区域进行保护,一次只能有一个线程获准进入该区域内进行操作。

一般代码中可以为需要保护的资源,声明一个CRITICAL_SECTION类型的变量,让其扮演红绿灯。

// 启动和关闭该变量

VOID InitializeCriticalSection(LPCRITICAL_SECTION  lpCriticalSection);

VOID DeleteCriticalSection(LPCRITICAL_SECTION  lpCriticalSection);

// 占用和释放该变量

VOID EnterCriticalSection(LPCRITICAL_SECTION  lpCriticalSection);

VOID LeaveCriticalSection(LPCRITICAL_SECTION  lpCriticalSection);

该些接口可以被调用多次,当然,释放时也得释放多次。

不要长时间锁住一份资源:千万不要在一个临界区域之中调用sleep或者任何wait之类的API函数。

我们没办法获知临界区中的那个线程是生是死,由于临界区域不是核心对象,如果进入临界区域的那个线程突然DOWN掉了,而没有调用LeaveCriticalSection()的话,系统没有办法将该临界区清除。所以,更好的方法就是使用mutex

死锁:

死锁就是线程互相等待。

避免死锁的方法就是寻找好的规约方法;

互斥(Mutex):

win32的mutex用途和临界区非常相似,但是它牺牲速度增加弹性。一个时间内只能够有一个线程拥有mutex。

1. 锁住一个未被拥有的mutex,比锁住一个未被拥有的临界区域变量需要花费更多的时间。

2. Mutex可以跨进程使用,但临界区域则只能够在一个进程中使用。

3. 等待一个mutex时,可以指定结束等待时间,避免占用者暴死现象。

产生一个互斥器(Mutex):

HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes,  BOOL bInitialOwner,  LPCTSTR lpName);

如果成功,则返回一个handle,否则返回null。调用GetLastError()可以获得进一步信息。

当你不再需要一个mutex时,可以使用CloseHandle()。

原文地址:https://www.cnblogs.com/davidsguo008/p/3607485.html