(零):基礎概念
當操作系統進入多道批處理系統時代以後,一個系統中就存在多個任務,每個任務都按照一定的算法進行調度來使用內存、cpu等共享資源。當其中一個任務等待其他資源時,該任務可以暫時睡眠,操作系統調度另外任務繼續執行額,這樣可以使系統資源得到最大化利用,而無需像以前單道批處理系統那樣只有當一個任務完成之後才執行下一個任務。但是由此也引入了多任務併發的問題。
併發就是多個任務同時執行,在現在的一般大型應用系統中,一個功能基本有多個任務共同完成,每個任務相互協調,互相配合以及交換信息,如此一來,我們需要考慮併發任務的同步與互斥了。
所謂同步,就是一件事情需要按照先後順序去完成,當一個任務和另一個任務通信時,任務A獲取另一個任務B的信息,當任務B未返回信息時,任務A持續等待,直到B返回信息回來,A再繼續執行。異步是和同步相對的一個概念,就是任務A向B請求信息時,不必等待B信息的返回,A請求完成之後直接做下一件事情。
所謂互斥就是某些資源在某一時刻只能由一個任務佔有,在某資源被任務A佔有的情況下,其他需要佔有該資源的任務B必須等待,任務A使用完該資源後釋放後任務B才能使用該資源。一般這樣的資源被稱作臨界資源,有的時候一段程序不允許併發執行,這段程序被稱作臨界區。
要解決同步互斥問題, 最主要的是理清楚活動者之間的同步關係, 還有某些問題中變量的互斥問題。我們來看看生產者消費者問題,生產者消費者問題是一個經典的進程同步問題。它描述的是: 有一群生產者進程在生產產品, 並將此產品提供給消費者進程去消費。為使生產者進程和消費者進程能併發執行, 在它們之間設置有個緩衝區的緩衝池, 生產者進程可將它所生產的產品放入一個緩衝區中,消費者進程可從一個緩衝區取得一個產品消費。儘管所有的生產者進程和消費者進程都是以異步的方式運行的,但它們之間必須保持同步,即不允許消費者進程到一個空緩衝區去取產品, 也不允許生產者進程向一個已裝滿產品的緩衝區投放產品。
我們這樣來描述這個問題, 假如緩衝池中有n個緩衝區,每個緩衝區存放一個消息,生產者和消費者進程(或線程)對緩衝區互斥的訪問。只要緩衝池未滿,生產者可將消息送入緩衝池;只要緩衝池未空,消費者可從緩衝池取走一個消息。 此時生產者和消費者需要保持同步,當緩衝池為空時,生產者通知消費者不要再來取數據,當不為空時,通知消費者可以來取數據。
在linux中,實現同步與互斥的方法有很多,比如信號量等,線程還有專用的線程互斥鎖以及條件變量。本系列文章將對各種實現同步互斥的方法進行分析以及給出示例,並且大多示例都基於生產者消費者模型來闡述。