学到的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、线程优先权
|