2024年3月14日发(作者:)

深入浅出Win32多线程程序设计之线程通信

简介

线程之间通信的两个基本问题是互斥和同步。

线程同步是指线程之间所具有的一种制约关系,一个线程的执行依赖另一个

线程的消息,当它没有得到另一个线程的消息时应等待,直到消息到达时才被唤

醒。

线程互斥是指对于共享的操作系统资源(指的是广义的"资源",而不是

Windows的.res文件,譬如全局变量就是一种共享资源),在各线程访问时 的

排它性。当有若干个线程都要使用某一共享资源时,任何时刻最多只允许一个线

程去使用,其它要使用该资源的线程必须等待,直到占用资源者释放该资源。

线程互斥是一种特殊的线程同步。

实际上,互斥和同步对应着线程间通信发生的两种情况:

(1)当有多个线程访问共享资源而不使资源被破坏时;

(2)当一个线程需要将某个任务已经完成的情况通知另外一个或多个线程

时。

在WIN32中,同步机制主要有以下几种:

(1)事件(Event);

(2)信号量(semaphore);

(3)互斥量(mutex);

(4)临界区(Critical section)。

全局变量

因为进程中的所有线程均可以访问所有的全局变量,因而全局变量成为

Win32多线程通信的最简单方式。例如:

int var; //全局变量

UINT ThreadFunction(LPVOIDpParam)

{

var = 0;

while (var < MaxValue)

{

//线程处理

::InterlockedIncrement(long*) &var);

}

return 0;

}

请看下列程序:

int globalFlag = false;

DWORD WINAPI ThreadFunc(LPVOID n)

{

Sleep(2000);

globalFlag = true;

return 0;

}

int main()

{

HANDLE hThrd;

DWORD threadId;

hThrd = CreateThread(NULL, 0, ThreadFunc, NULL, 0, &threadId);

if (hThrd)

{

printf("Thread launchedn");

CloseHandle(hThrd);

}

while (!globalFlag)

;

printf("exitn");

}

上述程序中使用全局变量和while循环查询进行线程间同步,实际上,这是

一种应该避免的方法,因为:

(1)当主线程必须使自己与ThreadFunc函数的完成运行实现同步时,它并

没有使自己进入睡眠状态。由于主线程没有进入睡眠状态,因此操作系统继续为

它调度C P U时间,这就要占用其他线程的宝贵时间周期;

(2)当主线程的优先级高于执行ThreadFunc函数的线程时,就会发生

globalFlag永远不能被赋值为true的情况。因为在这种情况下,系统决不会将

任何时间片分配给ThreadFunc线程。

事件

事件(Event)是WIN32提供的最灵活的线程间同步方式,事件可以处于激发