Win32 多线程学习笔记

学到的API函数

一、线程

创建线程、结束线程、获取线程的结束码

CreateThread

ExitThread

GetExitCodeThread

二、线程结束时触发

创建线程之后,等待线程的结束之后,再继续执行

WaitForSingleObject

创建多个线程之后,等待一组线程(或其中的一个)结束,再继续执行

WaitForMultipleObjects

将消息循环与内核对象的等待合并

MsgWaitForMultipleObjects

三、同步

SendMessage 是同步的

PostMessage 是异步的

1、临界区

初始化和销毁临界区的变量

InitializeCriticalSection

DeleteCriticalSection,不同于delete操作的释放内存

2、进入和离开临界区

临界区变量初始化之后,可以进入,然后可以离开

EnterCriticalSection

LeaveCriticalSection

一旦调用EnterCriticalSection进入某变量的临界区之后,仍然可以再次调用EnterCriticalSection进入该变量的临界区。但进入多少次,也要Leave多少次,该临界区才能被销毁。

临界区中不要调用Sleep或Wait...函数

临界区的不足:如果进入了临界区的线程结束了,而没有调用离开临界区的函数,该临界区将无法被销毁掉;而系统或其他线程是无法知道进入临界区的线程是否已经结束

避免这个不足,需要使用mutex

3、死锁

当有一段代码需要2个或更多资源(也就是至少进入两次临界区)时,可能会发生死锁

"all-or-nothing"(要不统统获得,要不统统没有),可以阻止死锁的发生

4、Mutex

Mutex的使用过程:

CreateMutex(创建Mutex时如果指定名称,则可以在进程间使用同一个Mutex。由于该名称整个操作系统都可以访问,所以需要避免重名)

OpenMutex

WaitForSingleObject 或 WaitForMultiObjects 或 MsgWaitForMultiObjects

ReleaseMutex

CloseHandle

5、信号量

等待一个数量为n的资源,当n=0时,就必须等待;使用,使n-1;释放,使n+1。如果n=1,就是Mutex。

CreateSemaphore 创建信号量(可以包含名称参数)

然后利用Wait...()函数可以锁定一个Semaphore

ReleaseSemaphore

请记住, lpPreviousCount 参数所传回来的是一个瞬间值。你不可以把lReleaseCount 加上 *lpPreviousCount,就当作是 semaphore 的现值,因为其他线程可能已经改变了 semaphore 的值。

6、事件
CreateEvent 创建事件
SetEvent  设置事件为激发状态
ResetEvent 设置事件为非激发状态(注意:不是重新设置为激发状态)
PulseEvent 如果是手动的ResetEvent,设置为激发状态后,则唤醒所有等待中的线程,然后变为非激发状态;如果是自动档ResetEvent,设置为激发状态后,则一个一个地唤醒等待中的线程

弊端:
1)激发event时没有线程在等待,则该event会被遗失
2)容易造成死锁

7、InterLocked变量
对于简单变量的互斥操作(比如计数器),如果用临界区或Mutex,相对来说会比较占用资源(相对计算器加1的操作而言),于是InterLocked变量出现了

InterlockedIncrement  值加1
InterlockedDecrement  值减1
InterlockedExchange   传入新值,返回旧值

四、线程控制

1、结束线程

TerminateThread 结束线程
缺点:
1)未给被结束线程一个清理自己内存的机会,或者被结束
2)导致内存泄漏
3)线程正进入临界区,则该临界区将永远处于锁定状态

2、线程优先权 

 

posted on 2014-07-09 16:24  海阔天  阅读(1102)  评论(0编辑  收藏  举报

导航