訊號驅動i/0是指程序預先告知核心,使得當某個描述字上發生某事時,核心使用訊號通知相關程序。
非同步i/0是程序執行i/0系統呼叫(比如讀或者寫),核心啟動i/0操作後立刻返回程序,程序可以在i/0操作執行期間繼續處理別的事情,然後當i/0操作成功或者失敗時,核心以程序預先設定的方式通知程序。
多個執行緒使用同乙個資料,必須保護該資料;
如果多個執行緒共用乙個基礎型別變數,應該宣告為volatile,防止編譯器使用將其快取到暫存器內的優化方式;
共享的整數變數應該優先使用原子操作來修改其值;
有時候,可以考慮將某些需要共享的資料只讓乙個單獨執行緒處理,然後將該執行緒作為一種服務提供給其他執行緒使用;
不確定的情況下,使用鎖來保護。
假設有很多執行緒共享乙個變數,只有乙個(或者很少的)執行緒負責修改這個變數的值,其他(或者大多數的)執行緒只是讀取變數的值。如果採用常規思路,所有執行緒訪問該變數都必須獲得乙個鎖,這樣的效率是很低的。因為如果寫變數的執行緒沒有執行對該變數的修改操作時,其他的讀執行緒理論上都可以安全的讀該變數的值。常規思路的解決方案讓所有的讀執行緒都排隊,所以我們需要readers/writers鎖來提供更好的效率。
在readers/writers鎖的解決方案裡,只要沒有任何執行緒在修改共享變數的值,所有其他執行緒都可以讀取該變數的值,如果有乙個執行緒正在修改共享變數的值,其他任何執行緒無論讀取還是改寫的操作都必須等待獲得鎖。這種解決方案適用於在寫操作較少,讀操作較多的多執行緒環境中。
readers/writers鎖有兩種策略,讀優先或者寫優先策略。讀優先策略是指總是讓讀操作先完成,寫優先是指只要有正在執行的或者等待的寫操作,讀操作就需要等待寫操作完成以後才能執行。圖書館書籍查詢系統通常使用讀操作,而航班預定系統由於強調資料的有效性,採用寫優先策略。
ace提供了跨平台的兩個類ace_rw_thread_mutex和ace_rw_process_mutex。
前者提供了執行緒間的同步,後者提供了程序範圍的同步。這兩個類採用了寫優先策略。ace的readers/writer鎖僅適用於讀操作較多而寫操作較少的多執行緒環境,注意在大多數其他情況下,readers/writers鎖都比採用mutex的常規思路慢。
(摘自訊號量是一種linux的資源,它可以讓不同的程序間進行相互通訊,因此它也被看作是ipc集中的一員。訊號量的作用是在兩個或多個程序訪問公共資源集時 保持同步。
訊號量是乙個計數器的值,它可以被幾個程序作為乙個集合以原子的方式執行。訊號量的計數器控制著對資源的訪問控制,訊號量提供了兩個主要的操作來處理計數器的值:
(1)資源的使用者在使用資源之前等待訊號量。如果訊號量的值為0,則繼續等待,如果大於0,則將訊號量值減1,使用者開始使用資源。
(2)資源的使用者在資源使用完畢後通知訊號量。使用者通知訊號量不再使用資源了,訊號量的值加1,檢查等待訊號量的使用者的序列,以確定是否有其他的使用者在等待之中。
使用訊號量進行程序間的通訊一般牽涉到以下操作:
相關訊號量的操作函式一般應該包含下面的標頭檔案;
#include
#include
#include
1.建立訊號量:在程式使用訊號量之前,必須首先建立訊號量。建立訊號量的函式原形如下所示:
int semget(key_t key,int nsems,int sem***);
引數說明:
(1)key:在本地系統中表示要建立或者訪問的訊號量集的關鍵字,當然為了避免與其他的訊號量產生衝突,我們可以簡單的利用ipc_private來表示乙個新建的訊號量。
(2)nsems:要建立或者要訪問的訊號量集中訊號量的數目。
(3)指定不同的選項和許可權位的標誌。可以為ipc_create,ipc_excl.
建立乙個新的訊號量:
int semid;
semid=semget(0x1234,2,ipc_create|ipc_excl|0600);
if(semid<0)
process error case.
}else
do the next thing;
使用已經存在的訊號量:
int semid;
semid=semget(0x1234,0,0);
if(semid<0)
{}else
2.初始化訊號集:
int semctl(int semid,int semnum,int cmd,union semun arg);
union semun
int val;
struct semid_ds *buf;
ushort *array;
eg:int semid;
int z;
union semun arg;
ushort initv=;
arg.array=initv;
z=semctl(semid,2,setall,arg);
int semop(int semid,struct sembuf *sops,unsigned nsops);
struct sembuf
short sem_num; /*訊號量的索引*/
short sem_op; /*訊號量的相關操作為乙個整數(正數表示通知訊號量,負數表示等待訊號量)*/
short sem_***;/*相關的操作標記*/
eg:int z;
static struct sembuf sops=
,z=semop(semid,sops,2);
如果是通知訊號量,則sembuf的值可以設為
static struct sembuf sops=
,z=semop(semid,sops,2);
4.刪除訊號量
當訊號量在系統中沒有用處後,應該將其刪除,這樣才能釋放核心中的支援表所占用的資源。
int semctl(int semid,int semnum,int cmd,union semun arg);
eg:int semid;
int z;
union semun arg;
z=semctl(semid,0,ipc_rmid,arg);
值得一提的是訊號量的使用遵循自願的原則的,也就是說訊號量並不能強制的限制應用程式對資源的訪問,我們在編寫每乙個程式的時候,都將通過資源的原則來執行如下操作:
1)在訪問受控資源前等待訊號量。
2)釋放受控的資源後要通知訊號量。
多程序與多執行緒(十二)
如圖1 postgresql基本結構圖,postgresql資料庫伺服器由幾個主程序組成 1.postmaster程序是乙個主管程序,它生成其他程序並監聽使用者連線。2.使用者程序 比如psql,或使用者應用程式通過jdbc等介面 用來處理互動式sql查詢。postmaster生成乙個或多個名為po...
多程序與多執行緒(十二)
如圖1 postgresql基本結構圖,postgresql資料庫伺服器由幾個主程序組成 1.postmaster程序是乙個主管程序,它生成其他程序並監聽使用者連線。2.使用者程序 比如psql,或使用者應用程式通過jdbc等介面 用來處理互動式sql查詢。postmaster生成乙個或多個名為po...
十二 java多執行緒之Exchanger
github 今天我們講最後乙個同步工具類exchanger,這個比較簡單,就是讓兩個執行緒交換資料.exchanger只有兩個方法而已,而且兩個還是一樣的,只是引數不通而已 看過海賊王的人都知道山治和路飛,山治是乙個廚師,手藝那是槓槓的.路飛則是乙個大胃王,超能吃.現在編寫乙個程式,讓山治不斷給路...