一 , 多线程简介:
首先在多线程之前先介绍下线程,介绍线程也离不开进程。(每一个程序最少拥有一个进程,且每一个进程最少拥有一个线程)
1_进程:是一个正在执行的程序(每一个程序最少拥有一个进程),每一个进程执行都有一个执行顺序,该顺序是一个执行路径或者叫一个控制单元。
2_线程: 就是一个进程中一个独立的控制单元。(一个进程至少包含一个线程)。
3_多线程:在一个进程中包含多个线程。目的是更好的利用资源或应用需求。
( C#的基础是C++,所以C#里面有很多C++的影子包括一些主要的概念。)
C++多线程同步:(信号量(Semaphore),事件(Event),互斥(Mutex),临界区(Critical Section))
一,什么是线程同步和互斥
同步就是协同步骤,按预先的先后次序进行运行。如:你说完,我再说。这里的同步千万不要理解同时进行,应是指协同协助,互相配合。线程同步是指多线程通过特定的设置(如互斥量,事件对象,临界区,信号量)来控制线程之间的执行(即所谓的同步)也可以说在线程之间通过同步建立起的执行顺序的关系,如果没有同步 ,那线程之间是各自运行各自的!
线程互斥是指对于共享的进程系统资源,在各单个线程访问时的排它性。当有若干个线都要使用某一共享资源时,任何时刻最多只允许一个线程去使用,其他要使用该资源的线程必须等待,知道占用资源者释放该资源为止。线程互斥可以看成是一种特殊的线程同步(下文统称为同步)。
二,线程同步的方式和机制:
1_临界区(Critical Section):
通过对多线程的串行化来访问公共资源或一段代码,速度快。适合控制数据访问,在任意时刻只允许一个线程对共享资源进行访问,如果有多个线程试图访问公共资源,那么再有一个线程进入后,其他试图访问公共资源的线程将被挂起,并一直等到临界区的线程离开,临界区在被释放后,其他线程才可以抢占。它并不是核心对象,不是属于操作系统维护的,而是属于进程维护的。
总结:
a)关键段共初始化,销毁,进入和离开关键区域四个函数。
b) 关键段可以解决线程的互斥问题,但因为具有“线程所有权”,所以无法解决同步问题。
c) 推荐关键段与旋转锁配合使用。
2_互斥(Mutex):
互斥对象和临界区很像,采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有一个,所以能保证公共资源不会同时被多个线程同时访问。当前拥有互斥和对象的线程处理完任务后必须将线程叫出来,以便其他线程访问资源。
总结:
a) 互斥量是内核对象,(重点:它与关键段都有“线程所有权”所以不能用于线程的同步)。
b) 互斥量能够用于多个进程之间的线程互斥问题,并且能完善的解决进程意外终止所造成的“遗弃”问题。
3_事件(Event):
通过通知操作的方式保持线程的同步,还可以方便实现对多个线程的优先级比较的操作。
总结 :
a) (事件是内核对象),事件分为手动置位事件和自动置位事件。事件Event内部包含一个使用计数(所有内核对象都有)。一个布尔值表示手动置位事件还是自动置位事件,另一个布尔值用来表示事件有无触发。
b) 事件可以由setEvent() 来触发,由ResetEvent() 来设置成未触发。还可以由PulseEvent()来发出一个事件脉冲。
c) 事件可以解决线程间同步问题,因此也能解决互斥问题。
4_信号量(Semaphore):
信号量也是内核对象。它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目。
总结(注意)
a) 再用CreateSemaphore()创建信号量时既要同时指出允许的最大资源计数和当前可用资源计数。一般是将当前可用资源计数设置为最大资源计数,每增加一个线程对共享资源的访问,当前可用资源计数就会减 1 ,只要当前可用资源计数大于 0 的,就可以发出信号量信号。但是当前可用计数减小到 0 时则说明当前占用资源的线程已经达到了所允许的最大数目。不能再允许其他线程的进入,此时的信号量将无法发出。线程在处理完共享资源后,应在离开的同事通过ReleaseSemaphore() 函数将当前可用资源计数加 1 。在任何时候当前可用资源计数绝不可能大于最大资源数计数。
(后续编辑,未完待续。。。)