线程同步的几种方式

---------------------用户模式下的同步对象----------------------
----------1、 临界区(CCriticalSection)-------------------
当多个线程访问一个独占性共享资源时,可以使用临界区对象。拥有临界区的线程可以访问被保护起来的资源或代码段,其他线程若想访问,则被挂起,直到拥有临界区的线程放弃临界区为止。

---------------------内核对象-------------------------------------------------------
----------2、事件(CEvent)------------------------------------
事件机制,分为自动重置事件对象和人工重置事件对象;
1)自动重置事件对象,一旦被触发(有信号,setEvent(h)),那么等待的所有线程中将只有一个线程能获得事件对象的句柄h,并同时自动的将此事件对象设置为无信号的,只有当这个线程执行完了,并且调用了setEvent(h)来触发这个事件对象,那么其他的线程才获得,总之每次只能有一个等待的线程获得事件对象,因为只要其中一个线程获得了此事件对象h,那么就会自动的将h设置成为无信号的状态,直到调用setEvent(h)来触发这个事件对象;它能够确保一个线程独占对一个资源的访问。
2)人工重置事件对象,一旦被触发(有信号,setEvent(h)),那么等待此事件对象的所有线程都将变成可调度的状态,CUP会随机的分配CPU时间给等待的所有线程,这些线程将同步的、随机的获取CPU的时间,来执行线程中的代码。
----------3、互斥量(CMutex)-------------------------------
1)互斥量对象(包含一个线程ID,能够知道是哪个线程访问了他)能够确保一个线程独占对一个资源的访问。
2)如果线程ID为0(无效线程ID),那么互斥量将不为任何线程所占有,他处于触发状态;
3)如果线程ID为非零,那么有一个线程已经占用了这个互斥量,它处于未触发的状态;
4)与所有其他内核对象不同,假设线程视图等待一个未触发的互斥量对象,在这种情况下,线程通常会进入等待状态,但是,系统会检查想要获得互斥量的线程的线程ID与互斥量对象内部记录的线程ID是否相同,如果相同,那么系统会让线程保持可调度状态,即使该互斥量尚未触发。
互斥量与临界区的行为完全相同,但是区别如下:
1)互斥量是内核对象,临界区是用户模式下的同步对象,执行速度快于内核对象;
2)不同进程中的线程可以访问同一个互斥量,而且还可以设置等待的最长时间。
-----------4、信号量(CSemphore)----------------------------
信号量与其他所有内核对象相同,但是另外又包含了两个32位的值:
一个是最大资源计数,一个是当前资源计数。
1)最大资源计数表示信号量可以控制的最大资源数量(这个是在创建信号量的时候就已经设定好了);
2)当前资源计数表示信号量当前可用资源数量;
信号量的规则如下:
1)如果当前资源计数大于0,那么信号量处于触发状态;
2)如果当前资源计数等于0,那么信号处于未触发状态;
3)系统绝对不会让当前资源计数变为负数;
4)当前资源计数绝对不会大于最大资源计数。

猜你喜欢

转载自blog.csdn.net/qiuyoujie/article/details/79655086