C++多线程通信:互斥与同步


在一个多线程的应用程序中,所有线程共享进程资源,协同工作。所以,线程之间的通信是编写多线程应用的必不可少的环节。线程之间的通信包括互斥、同步等,它是多线程设计中最难控制的部分,也是关键部分。

1、线程间的互斥(a执行时b不能执行)

(1) 临界区
  在一个多线程的应用程序中,可能存在这样的危险:一个线程以某种其他线程不可预料的方式修改资源。
  例如两个线程都对同一个文件进行读写,两个线程都在进行绘图,一个线程正在使用一段内存而另一个线程却正在修改这段内存的值等,都可能出现不可预料的结果。
  可以把不允许多个线程交叉运行的一段程序称为临界区。它是由于多个线程共享公用数据或公用变量而引起的。
  临界区也被称为:访问公用数据的那段程序。

(2) 互斥
  为使多个线程在进入自己的临界区时不出现问题,需要实现线程的互斥运行。它应满足:
   ·各线程平等,都可随时进入临界区。
   ·一个不在临界区执行的线程,不可以阻止其他线程进入临界区。
   ·当一个线程正在临界区内执行时,必须阻止其他线程进入临界区。
   ·多个线程申请进入临界区时,只能允许一个线程进入。
   ·一个申请进入临界区的线程,应该能在有限时间内进入,不会发生死锁。

(3) 临界区类
  MFC定义了临界区封装类CCriticalSection,可以比较方便的实现线程间的互斥。
  首先定义一个CCriticalSection类对象,该对象通常应被定义为全局变量,以便跨线程使用。
  当线程要进入临界区时,调用其成员函数Lock()。若临界区空闲,该函数将锁定临界区;若临界区已经被锁定,该函数将被阻塞(不耗费机时),直至临界区解锁。
  当线程要退出临界区时,调用其成员函数Unlock()解锁,以便其他线程可以进入临界区。

使用临界区,实现线程互斥。

2、线程间的同步(b执行的前提是a执行完毕)

有时一个线程的执行条件是另一个线程的执行结果,所以只有等待另一个线程完成某项操作后,该线程才可继续执行。例如计算线程和打印线程。
  这种由于线程间的功能逻辑关系引起的,称为线程间的直接制约。而由于共享资源引起的线程执行速度的制约,称为间接制约。
  存在直接制约关系的一个线程可以在另一个线程的执行条件满足后,给对方发送相应消息或信号。这样,被制约的线程可以在条件不满足时处于阻塞状态,条件满足后,被对方唤醒继续工作。
  这就是线程间的同步方式。

等待函数和事件对象、互斥对象、信号量对象等一起使用,实现线程同步。

发布了88 篇原创文章 · 获赞 16 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/WHEgqing/article/details/105216267
今日推荐