同步多个线程的执行

为了避免争用条件和死锁,需要将多个线程对共享资源的访问同步。 若要确保以正确的顺序执行相互依赖的代码,还需要同步。

有许多对象,其句柄可用于同步多个线程。 这些对象包括:

  • 控制台输入缓冲区
  • 事件
  • Mutexes
  • 进程
  • 信号灯
  • 线程数
  • 计时器

其中每个对象的状态要么已发出信号,要么未发出信号。 在调用其中一个 wait 函数时指定其中任何对象的句柄时,将阻止调用线程的执行,直到指定对象的状态得到信号。

其中一些对象可用于阻止线程,直到发生某些事件。 例如,当存在未读输入(例如击键或单击鼠标按钮)时,控制台输入缓冲区句柄会发出信号。 进程和线程句柄在进程或线程终止时发出信号。 例如,这允许进程创建一个子进程,然后阻止其自己的执行,直到新进程终止。

其他对象可用于保护共享资源免受同时访问。 例如,多个线程可以每个线程都有一个互斥对象的句柄。 在访问共享资源之前,线程必须调用其中一个 等待函数 来等待互斥的状态被发出信号。 当互斥体发出信号时,只会释放一个等待的线程来访问资源。 互斥锁的状态会立即重置为未发出信号,因此任何其他等待线程仍被阻止。 当线程用完资源时,它必须将互斥锁的状态设置为“已发出信号”,以允许其他线程访问资源。

对于单个进程的线程,关键部分对象比互斥体提供更高效的同步方式。 关键部分类似于互斥体,一次允许一个线程使用受保护的资源。 线程可以使用 EnterCriticalSection 函数请求关键节的所有权。 如果它已由另一个线程拥有,则请求线程将被阻止。 线程可以使用 TryEnterCriticalSection 函数请求关键节的所有权,而不会在获取关键节失败时阻塞。 获得所有权后,线程可以自由使用受保护的资源。 进程的其他线程的执行不受影响,除非它们尝试进入同一关键部分。

WaitForInputIdle 函数使线程等待到指定的进程初始化并等待用户输入,而没有挂起的输入。 调用 WaitForInputIdle 可用于同步父进程和子进程,因为 CreateProcess 返回时不会等待子进程完成其初始化。

有关详细信息,请参阅 同步