为了避免竞争条件和死锁,非常有必要做一些多线程存取共享资源的同步工作。对于确保几个相关的代码能够以正确的顺序执行,同步也非常重要。
下面的这些对象可以用于多线程同步:
Console input buffers
Events
Mutexes
Processes
Semaphores
Threads
Timers
这些对象都有两个状态:已被标记(signaled),未被标记(not signaled)。如果使用任意一个这种对象来调用某个等待函数(WaitForSingleObject等),在这个对象的状态变成已被标记之前,线程都会处在阻止状态。
这些对象对于阻止线程直到在某些事件发生很有用。举一个例子,如果有一个未被读取的输入,比如一次键盘敲击或者鼠标点击,控制台输入缓存句柄会变成已被标记状态。进程或线程终止后,它们的句柄会变成已被标记状态。这样就允许进程在创建了一个子进程后立刻挂起自己,直到进程终止运行。
另一些对象对于保护共享资源很有用。举个例子,有多个线程需要访问同一个资源,每一个线程都有同一个mutex对象的句柄。在访问这个共享资源之前,所有的这些线程都必须调用等待函数,等待mutex对象变成已被标记状态。当mutex对象变成已被标记状态时,只有一个线程被允许访问这个资源。与此同时,mutex对象又被马上设置为违背标记状态,所以其它的线程还是被阻止着。一旦线程完成了对资源的访问,它必须把mutex对象再次设置为已被标记状态,使得其他线程可以访问这个资源。
对于单一进程中的线程,关键区域(critical-section)对象比起同步对象,提供了一个更为有效的手段。关键区域作用和同步对象一样,都是允许同一时间只有一个线程可以访问资源。线程调用EnterCriticalSection函数来要求取得关键区域。如果这个关键区域已经被别的线程占领了,这个线程就会被阻止。在取得关键区域之后,线程就可以访问共享资源了。如果进程中的其它线程没有试图取得关键区域,则关键区域的互斥作用对他们无效。
Console input buffers
Events
Mutexes
Processes
Semaphores
Threads
Timers
这些对象都有两个状态:已被标记(signaled),未被标记(not signaled)。如果使用任意一个这种对象来调用某个等待函数(WaitForSingleObject等),在这个对象的状态变成已被标记之前,线程都会处在阻止状态。
这些对象对于阻止线程直到在某些事件发生很有用。举一个例子,如果有一个未被读取的输入,比如一次键盘敲击或者鼠标点击,控制台输入缓存句柄会变成已被标记状态。进程或线程终止后,它们的句柄会变成已被标记状态。这样就允许进程在创建了一个子进程后立刻挂起自己,直到进程终止运行。
另一些对象对于保护共享资源很有用。举个例子,有多个线程需要访问同一个资源,每一个线程都有同一个mutex对象的句柄。在访问这个共享资源之前,所有的这些线程都必须调用等待函数,等待mutex对象变成已被标记状态。当mutex对象变成已被标记状态时,只有一个线程被允许访问这个资源。与此同时,mutex对象又被马上设置为违背标记状态,所以其它的线程还是被阻止着。一旦线程完成了对资源的访问,它必须把mutex对象再次设置为已被标记状态,使得其他线程可以访问这个资源。
对于单一进程中的线程,关键区域(critical-section)对象比起同步对象,提供了一个更为有效的手段。关键区域作用和同步对象一样,都是允许同一时间只有一个线程可以访问资源。线程调用EnterCriticalSection函数来要求取得关键区域。如果这个关键区域已经被别的线程占领了,这个线程就会被阻止。在取得关键区域之后,线程就可以访问共享资源了。如果进程中的其它线程没有试图取得关键区域,则关键区域的互斥作用对他们无效。