科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件深入浅出Win32多线程程序设计之线程通信

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

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

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

作者:宋宝华 来源:天极开发 2007年10月16日

关键字:

  • 评论
  • 分享微博
  • 分享邮件

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

2005-12-16 08:48 作者: 宋宝华 出处: 天极开发 责任编辑:方舟
  临界区

  定义临界区变量

CRITICAL_SECTION gCriticalSection;

  通常情况下,CRITICAL_SECTION结构体应该被定义为全局变量,以便于进程中的所有线程方便地按照变量名来引用该结构体。

  初始化临界区

VOID WINAPI InitializeCriticalSection(
 LPCRITICAL_SECTION lpCriticalSection
 //指向程序员定义的CRITICAL_SECTION变量
);

  该函数用于对pcs所指的CRITICAL_SECTION结构体进行初始化。该函数只是设置了一些成员变量,它的运行一般不会失败,因此它采用了VOID类型的返回值。该函数必须在任何线程调用EnterCriticalSection函数之前被调用,如果一个线程试图进入一个未初始化的CRTICAL_SECTION,那么结果将是很难预计的。

  删除临界区

VOID WINAPI DeleteCriticalSection(
 LPCRITICAL_SECTION lpCriticalSection
 //指向一个不再需要的CRITICAL_SECTION变量
);

  进入临界区

VOID WINAPI EnterCriticalSection(
 LPCRITICAL_SECTION lpCriticalSection
 //指向一个你即将锁定的CRITICAL_SECTION变量
);

  离开临界区

VOID WINAPI LeaveCriticalSection(
 LPCRITICAL_SECTION lpCriticalSection
 //指向一个你即将离开的CRITICAL_SECTION变量
);

  使用临界区编程的一般方法是:

void UpdateData()
{
 EnterCriticalSection(&gCriticalSection);
 ...//do something
 LeaveCriticalSection(&gCriticalSection);
}

  关于临界区的使用,有下列注意点:

  (1)每个共享资源使用一个CRITICAL_SECTION变量;

  (2)不要长时间运行关键代码段,当一个关键代码段长时间运行时,其他线程就会进入等待状态,这会降低应用程序的运行性能;

  (3)如果需要同时访问多个资源,则可能连续调用EnterCriticalSection;

  (4)Critical Section不是OS核心对象,如果进入临界区的线程"挂"了,将无法释放临界资源。这个缺点在Mutex中得到了弥补。

  互斥

  互斥量的作用是保证每次只能有一个线程获得互斥量而得以继续执行,使用CreateMutex函数创建:

HANDLE CreateMutex(
 LPSECURITY_ATTRIBUTES lpMutexAttributes,
 // 安全属性结构指针,可为NULL
 BOOL bInitialOwner,
 //是否占有该互斥量,TRUE:占有,FALSE:不占有
 LPCTSTR lpName
 //信号量的名称
);

  Mutex是核心对象,可以跨进程访问,下面的代码给出了从另一进程访问命名Mutex的例子:

HANDLE hMutex;
hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, L"mutexName");
if (hMutex){
 …

else{
 …
}

  相关API:

BOOL WINAPI ReleaseMutex(
 HANDLE hMutex
);

  使用互斥编程的一般方法是:

void UpdateResource()
{
 WaitForSingleObject(hMutex,…);
 ...//do something
 ReleaseMutex(hMutex);
}

  互斥(mutex)内核对象能够确保线程拥有对单个资源的互斥访问权。互斥对象的行为特性与临界区相同,但是互斥对象属于内核对象,而临界区则属于用户方式对象,因此这导致mutex与Critical Section的如下不同:

  (1) 互斥对象的运行速度比关键代码段要慢;

  (2) 不同进程中的多个线程能够访问单个互斥对象;

  (3) 线程在等待访问资源时可以设定一个超时值。

  下图更详细地列出了互斥与临界区的不同:

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章