在做项目时,难免会碰到多线程问题,在进行多线程编程时,难免会遇到多线程的互斥与同步操作。
线程的同步就是协同步调,按预定的先后次序进行运行。如:你说完,我再说或者可以这么理解,进程、线程同步,可理解为进程或线程A和B一块配合,A执行到一定程度时要依靠B的某个结果,于是停下来,示意B运行;B依言执行,再将结果给A;A再继续操作。
线程互斥是指对于共享的进程系统资源,在各单个线程访问时的排它性。当有若干个线程都要使用某一共享资源时,任何时刻最多只允许一个线程去使用,其它要使用该资源的线程必须等待,直到占用资源者释放该资源。线程互斥可以看成是一种特殊的线程同步(下文统称为同步)。
线程间的同步方法大体可分为两类:用户模式和内核模式。内核模式就是指利用系统内核对象的单一性来进行同步,使用时需要切换内核态与用户态;而用户模式就是不需要切换到内核态,只在用户态完成操作。
用户模式下的方法有:临界区;内核模式下的方法有:事件,信号量,互斥量。
临界区、互斥量、事件、信号量四种方式简介(临界区(Critical Section)、互斥量(Mutex)、信号量(Semaphore)、事件(Event):
1、临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。在任意时刻只允许一个线程对共享资源进行访问,如果有多个线程试图访问公共资源,那么在有一个线程进入后,其他试图访问公共资源的线程将被挂起,并一直等到进入临界区的线程离开,临界区在被释放后,其他线程才可以抢占。
临界区包含两个操作原语:
EnterCriticalSection() 进入临界区
LeaveCriticalSection() 离开临界区
2、互斥量:采用互斥对象机制。 只有拥有互斥对象的线程才有访问公共资源的权限,因为互斥对象只有一个,所以能保证公共资源不会同时被多个线程访问。互斥不仅能实现同一应用程序的公共资源安全共享,还能实现不同应用程序的公共资源安全共享。
互斥量包含的几个操作原语:
CreateMutex() //创建一个互斥量
OpenMutex() //打开一个互斥量
ReleaseMutex() //释放互斥量
WaitForMultipleObjects() //等待互斥量对象
3、信号量:它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目
信号量包含的几个操作原语:
CreateSemaphore() //创建一个信号量
OpenSemaphore() //打开一个信号量
ReleaseSemaphore() //释放信号量
WaitForSingleObject() //等待信号量
4、事 件: 通过通知操作的方式来保持线程的同步,还可以方便实现对多个线程的优先级比较的操作。
CreateEvent() //创建一个信号量
OpenEvent() // 打开一个事件
SetEvent() //回置事件
WaitForSingleObject() //等待一个事件
WaitForMultipleObjects() // 等待多个事件
WaitForMultipleObjects( //原型
DWORD nCount,
// 等待句柄数
CONST HANDLE *lpHandles,
//指向句柄数组
BOOL bWaitAll,
//是否完全等待标志
DWORD dwMilliseconds
//等待时间
)