青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Prayer

在一般中尋求卓越
posts - 1256, comments - 190, trackbacks - 0, articles - 0
  C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

一、信號(hào)燈概述

信號(hào)燈與其他進(jìn)程間通信方式不大相同,它主要提供對(duì)進(jìn)程間共享資源訪問控制機(jī)制。相當(dāng)于內(nèi)存中的標(biāo)志,進(jìn)程可以根據(jù)它判定是否能夠訪問某些共享資源,同時(shí),進(jìn)程也可以修改該標(biāo)志。除了用于訪問控制外,還可用于進(jìn)程同步。信號(hào)燈有以下兩種類型:

  • 二值信號(hào)燈:最簡單的信號(hào)燈形式,信號(hào)燈的值只能取0或1,類似于互斥鎖。
    注:二值信號(hào)燈能夠?qū)崿F(xiàn)互斥鎖的功能,但兩者的關(guān)注內(nèi)容不同。信號(hào)燈強(qiáng)調(diào)共享資源,只要共享資源可用,其他進(jìn)程同樣可以修改信號(hào)燈的值;互斥鎖更強(qiáng)調(diào)進(jìn)程,占用資源的進(jìn)程使用完資源后,必須由進(jìn)程本身來解鎖。
  • 計(jì)算信號(hào)燈:信號(hào)燈的值可以取任意非負(fù)值(當(dāng)然受內(nèi)核本身的約束)。

二、Linux信號(hào)燈

linux對(duì)信號(hào)燈的支持狀況與消息隊(duì)列一樣,在red had 8.0發(fā)行版本中支持的是系統(tǒng)V的信號(hào)燈。因此,本文將主要介紹系統(tǒng)V信號(hào)燈及其相應(yīng)API。在沒有聲明的情況下,以下討論中指的都是系統(tǒng)V信號(hào)燈。

注意,通常所說的系統(tǒng)V信號(hào)燈指的是計(jì)數(shù)信號(hào)燈集。

三、信號(hào)燈與內(nèi)核

1、系統(tǒng)V信號(hào)燈是隨內(nèi)核持續(xù)的,只有在內(nèi)核重起或者顯示刪除一個(gè)信號(hào)燈集時(shí),該信號(hào)燈集才會(huì)真正被刪除。因此系統(tǒng)中記錄信號(hào)燈的數(shù)據(jù)結(jié)構(gòu)(struct ipc_ids sem_ids)位于內(nèi)核中,系統(tǒng)中的所有信號(hào)燈都可以在結(jié)構(gòu)sem_ids中找到訪問入口。

2、下圖說明了內(nèi)核與信號(hào)燈是怎樣建立起聯(lián)系的:

其中:struct ipc_ids sem_ids是內(nèi)核中記錄信號(hào)燈的全局?jǐn)?shù)據(jù)結(jié)構(gòu);描述一個(gè)具體的信號(hào)燈及其相關(guān)信息。

其中,struct sem結(jié)構(gòu)如下:

struct sem{
int semval; // current value
int sempid // pid of last operation
}

從上圖可以看出,全局?jǐn)?shù)據(jù)結(jié)構(gòu)struct ipc_ids sem_ids可以訪問到struct kern_ipc_perm的第一個(gè)成員:struct kern_ipc_perm;而每個(gè)struct kern_ipc_perm能夠與具體的信號(hào)燈對(duì)應(yīng)起來是因?yàn)樵谠摻Y(jié)構(gòu)中,有一個(gè)key_t類型成員key,而key則唯一確定一個(gè)信號(hào)燈集;同時(shí),結(jié)構(gòu) struct kern_ipc_perm的最后一個(gè)成員sem_nsems確定了該信號(hào)燈在信號(hào)燈集中的順序,這樣內(nèi)核就能夠記錄每個(gè)信號(hào)燈的信息了。 kern_ipc_perm結(jié)構(gòu)參見《Linux環(huán)境進(jìn)程間通信(三):消息隊(duì)列》。struct sem_array見附錄1。

四、操作信號(hào)燈

對(duì)消息隊(duì)列的操作無非有下面三種類型:

1、 打開或創(chuàng)建信號(hào)燈
與消息隊(duì)列的創(chuàng)建及打開基本相同,不再詳述。

2、 信號(hào)燈值操作
linux可以增加或減小信號(hào)燈的值,相應(yīng)于對(duì)共享資源的釋放和占有。具體參見后面的semop系統(tǒng)調(diào)用。

3、 獲得或設(shè)置信號(hào)燈屬性:
系統(tǒng)中的每一個(gè)信號(hào)燈集都對(duì)應(yīng)一個(gè)struct sem_array結(jié)構(gòu),該結(jié)構(gòu)記錄了信號(hào)燈集的各種信息,存在于系統(tǒng)空間。為了設(shè)置、獲得該信號(hào)燈集的各種信息及屬性,在用戶空間有一個(gè)重要的聯(lián)合結(jié)構(gòu)與之對(duì)應(yīng),即union semun。

聯(lián)合semun數(shù)據(jù)結(jié)構(gòu)各成員意義參見附錄2

信號(hào)燈API

1、文件名到鍵值

#i nclude 
#i nclude
key_t ftok (char*pathname, char proj);

它返回與路徑pathname相對(duì)應(yīng)的一個(gè)鍵值,具體用法請(qǐng)參考《Linux環(huán)境進(jìn)程間通信(三):消息隊(duì)列》。

2、 linux特有的ipc()調(diào)用:

int ipc(unsigned int call, int first, int second, int third, void *ptr, long fifth);

參數(shù)call取不同值時(shí),對(duì)應(yīng)信號(hào)燈的三個(gè)系統(tǒng)調(diào)用:
當(dāng)call為SEMOP時(shí),對(duì)應(yīng)int semop(int semid, struct sembuf *sops, unsigned nsops)調(diào)用;
當(dāng)call為SEMGET時(shí),對(duì)應(yīng)int semget(key_t key, int nsems, int semflg)調(diào)用;
當(dāng)call為SEMCTL時(shí),對(duì)應(yīng)int semctl(int semid,int semnum,int cmd,union semun arg)調(diào)用;
這些調(diào)用將在后面闡述。

注:本人不主張采用系統(tǒng)調(diào)用ipc(),而更傾向于采用系統(tǒng)V或者POSIX進(jìn)程間通信API。原因已在Linux環(huán)境進(jìn)程間通信(三):消息隊(duì)列中給出。

3、系統(tǒng)V信號(hào)燈API

系統(tǒng)V消息隊(duì)列API只有三個(gè),使用時(shí)需要包括幾個(gè)頭文件:

#i nclude 
#i nclude
#i nclude

1)int semget(key_t key, int nsems, int semflg)
參數(shù)key是一個(gè)鍵值,由ftok獲得,唯一標(biāo)識(shí)一個(gè)信號(hào)燈集,用法與msgget()中的key相同;參數(shù)nsems指定打開或者新創(chuàng)建的信號(hào)燈集中將包含信號(hào)燈的數(shù)目;semflg參數(shù)是一些標(biāo)志位。參數(shù)key和semflg的取值,以及何時(shí)打開已有信號(hào)燈集或者創(chuàng)建一個(gè)新的信號(hào)燈集與msgget()中的對(duì)應(yīng)部分相同,不再祥述。
該調(diào)用返回與健值key相對(duì)應(yīng)的信號(hào)燈集描述字。
調(diào)用返回:成功返回信號(hào)燈集描述字,否則返回-1。
注:如果key所代表的信號(hào)燈已經(jīng)存在,且semget指定了IPC_CREAT|IPC_EXCL標(biāo)志,那么即使參數(shù)nsems與原來信號(hào)燈的數(shù)目不等,返回的也是EEXIST錯(cuò)誤;如果semget只指定了IPC_CREAT標(biāo)志,那么參數(shù)nsems必須與原來的值一致,在后面程序?qū)嵗羞€要進(jìn)一步說明。

2)int semop(int semid, struct sembuf *sops, unsigned nsops);
semid是信號(hào)燈集ID,sops指向數(shù)組的每一個(gè)sembuf結(jié)構(gòu)都刻畫一個(gè)在特定信號(hào)燈上的操作。nsops為sops指向數(shù)組的大小。
sembuf結(jié)構(gòu)如下:

struct sembuf {
unsigned short sem_num; /* semaphore index in array */
short sem_op; /* semaphore operation */
short sem_flg; /* operation flags */
};

sem_num對(duì)應(yīng)信號(hào)集中的信號(hào)燈,0對(duì)應(yīng)第一個(gè)信號(hào)燈。sem_flg可取IPC_NOWAIT以及SEM_UNDO兩個(gè)標(biāo)志。如果設(shè)置了SEM_UNDO標(biāo)志,那么在進(jìn)程結(jié)束時(shí),相應(yīng)的操作將被取消,這是比較重要的一個(gè)標(biāo)志位。如果設(shè)置了該標(biāo)志位,那么在進(jìn)程沒有釋放共享資源就退出時(shí),內(nèi)核將代為釋放。如果為一個(gè)信號(hào)燈設(shè)置了該標(biāo)志,內(nèi)核都要分配一個(gè)sem_undo結(jié)構(gòu)來記錄它,為的是確保以后資源能夠安全釋放。事實(shí)上,如果進(jìn)程退出了,那么它所占用就釋放了,但信號(hào)燈值卻沒有改變,此時(shí),信號(hào)燈值反映的已經(jīng)不是資源占有的實(shí)際情況,在這種情況下,問題的解決就靠內(nèi)核來完成。這有點(diǎn)像僵尸進(jìn)程,進(jìn)程雖然退出了,資源也都釋放了,但內(nèi)核進(jìn)程表中仍然有它的記錄,此時(shí)就需要父進(jìn)程調(diào)用waitpid來解決問題了。
sem_op的值大于0,等于0以及小于0確定了對(duì)sem_num指定的信號(hào)燈進(jìn)行的三種操作。具體請(qǐng)參考linux相應(yīng)手冊(cè)頁。
這里需要強(qiáng)調(diào)的是semop同時(shí)操作多個(gè)信號(hào)燈,在實(shí)際應(yīng)用中,對(duì)應(yīng)多種資源的申請(qǐng)或釋放。semop保證操作的原子性,這一點(diǎn)尤為重要。尤其對(duì)于多種資源的申請(qǐng)來說,要么一次性獲得所有資源,要么放棄申請(qǐng),要么在不占有任何資源情況下繼續(xù)等待,這樣,一方面避免了資源的浪費(fèi);另一方面,避免了進(jìn)程之間由于申請(qǐng)共享資源造成死鎖。
也許從實(shí)際含義上更好理解這些操作:信號(hào)燈的當(dāng)前值記錄相應(yīng)資源目前可用數(shù)目;sem_op>0對(duì)應(yīng)相應(yīng)進(jìn)程要釋放 sem_op數(shù)目的共享資源;sem_op=0可以用于對(duì)共享資源是否已用完的測試;sem_op<0相當(dāng)于進(jìn)程要申請(qǐng)-sem_op個(gè)共享資源。再聯(lián)想操作的原子性,更不難理解該系統(tǒng)調(diào)用何時(shí)正常返回,何時(shí)睡眠等待。
調(diào)用返回:成功返回0,否則返回-1。

3) int semctl(int semid,int semnum,int cmd,union semun arg)
該系統(tǒng)調(diào)用實(shí)現(xiàn)對(duì)信號(hào)燈的各種控制操作,參數(shù)semid指定信號(hào)燈集,參數(shù)cmd指定具體的操作類型;參數(shù)semnum指定對(duì)哪個(gè)信號(hào)燈操作,只對(duì)幾個(gè)特殊的cmd操作有意義;arg用于設(shè)置或返回信號(hào)燈信息。
該系統(tǒng)調(diào)用詳細(xì)信息請(qǐng)參見其手冊(cè)頁,這里只給出參數(shù)cmd所能指定的操作。
IPC_STAT 獲取信號(hào)燈信息,信息由arg.buf返回;
IPC_SET 設(shè)置信號(hào)燈信息,待設(shè)置信息保存在arg.buf中(在manpage中給出了可以設(shè)置哪些信息);
GETALL 返回所有信號(hào)燈的值,結(jié)果保存在arg.array中,參數(shù)sennum被忽略;
GETNCNT 返回等待semnum所代表信號(hào)燈的值增加的進(jìn)程數(shù),相當(dāng)于目前有多少進(jìn)程在等待semnum代表的信號(hào)燈所代表的共享資源;
GETPID 返回最后一個(gè)對(duì)semnum所代表信號(hào)燈執(zhí)行semop操作的進(jìn)程ID;
GETVAL 返回semnum所代表信號(hào)燈的值;
GETZCNT 返回等待semnum所代表信號(hào)燈的值變成0的進(jìn)程數(shù);
SETALL 通過arg.array更新所有信號(hào)燈的值;同時(shí),更新與本信號(hào)集相關(guān)的semid_ds結(jié)構(gòu)的sem_ctime成員;
SETVAL 設(shè)置semnum所代表信號(hào)燈的值為arg.val;

調(diào)用返回:調(diào)用失敗返回-1,成功返回與cmd相關(guān):

Cmd return value
GETNCNT Semncnt
GETPID Sempid
GETVAL Semval
GETZCNT Semzcnt

五、信號(hào)燈的限制

1、 一次系統(tǒng)調(diào)用semop可同時(shí)操作的信號(hào)燈數(shù)目SEMOPM,semop中的參數(shù)nsops如果超過了這個(gè)數(shù)目,將返回E2BIG錯(cuò)誤。SEMOPM的大小特定與系統(tǒng),redhat 8.0為32。

2、 信號(hào)燈的最大數(shù)目:SEMVMX,當(dāng)設(shè)置信號(hào)燈值超過這個(gè)限制時(shí),會(huì)返回ERANGE錯(cuò)誤。在redhat 8.0中該值為32767。

3、 系統(tǒng)范圍內(nèi)信號(hào)燈集的最大數(shù)目SEMMNI以及系統(tǒng)范圍內(nèi)信號(hào)燈的最大數(shù)目SEMMNS。超過這兩個(gè)限制將返回ENOSPC錯(cuò)誤。redhat 8.0中該值為32000。

4、 每個(gè)信號(hào)燈集中的最大信號(hào)燈數(shù)目SEMMSL,redhat 8.0中為250。 SEMOPM以及SEMVMX是使用semop調(diào)用時(shí)應(yīng)該注意的;SEMMNI以及SEMMNS是調(diào)用semget時(shí)應(yīng)該注意的。SEMVMX同時(shí)也是semctl調(diào)用應(yīng)該注意的。

六、競爭問題

第一個(gè)創(chuàng)建信號(hào)燈的進(jìn)程同時(shí)也初始化信號(hào)燈,這樣,系統(tǒng)調(diào)用semget包含了兩個(gè)步驟:創(chuàng)建信號(hào)燈;初始化信號(hào)燈。由此可能導(dǎo)致一種競爭狀態(tài):第一個(gè)創(chuàng)建信號(hào)燈的進(jìn)程在初始化信號(hào)燈時(shí),第二個(gè)進(jìn)程又調(diào)用semget,并且發(fā)現(xiàn)信號(hào)燈已經(jīng)存在,此時(shí),第二個(gè)進(jìn)程必須具有判斷是否有進(jìn)程正在對(duì)信號(hào)燈進(jìn)行初始化的能力。在參考文獻(xiàn)[1]中,給出了繞過這種競爭狀態(tài)的方法:當(dāng)semget創(chuàng)建一個(gè)新的信號(hào)燈時(shí),信號(hào)燈結(jié)構(gòu)semid_ds的 sem_otime成員初始化后的值為0。因此,第二個(gè)進(jìn)程在成功調(diào)用semget后,可再次以IPC_STAT命令調(diào)用semctl,等待 sem_otime變?yōu)榉?值,此時(shí)可判斷該信號(hào)燈已經(jīng)初始化完畢。下圖描述了競爭狀態(tài)產(chǎn)生及解決方法:

實(shí)際上,這種解決方法也是基于這樣一個(gè)假定:第一個(gè)創(chuàng)建信號(hào)燈的進(jìn)程必須調(diào)用semop,這樣sem_otime才能變?yōu)榉橇阒怠A硗猓驗(yàn)榈谝粋€(gè)進(jìn)程可能不調(diào)用semop,或者semop操作需要很長時(shí)間,第二個(gè)進(jìn)程可能無限期等待下去,或者等待很長時(shí)間。

七、信號(hào)燈應(yīng)用實(shí)例

本實(shí)例有兩個(gè)目的:1、獲取各種信號(hào)燈信息;2、利用信號(hào)燈實(shí)現(xiàn)共享資源的申請(qǐng)和釋放。并在程序中給出了詳細(xì)注釋。


#i nclude
#i nclude
#i nclude
#define SEM_PATH "/unix/my_sem"
#define max_tries 3

int semid;
main()
{
int flag1,flag2,key,i,init_ok,tmperrno;
struct semid_ds sem_info;
struct seminfo sem_info2;
union semun arg; //union semun: 請(qǐng)參考附錄2
struct sembuf askfor_res, free_res;
flag1=IPC_CREAT|IPC_EXCL|00666;
flag2=IPC_CREAT|00666;
key=ftok(SEM_PATH,'a');
//error handling for ftok here;
init_ok=0;
semid=semget(key,1,flag1);//create a semaphore set that only includes one semphore.
if(semid<0)
{
tmperrno=errno;
perror("semget");
if(tmperrno==EEXIST)
//errno is undefined after a successful library call( including perror call) so it is saved //in tmperrno.
{
semid=semget(key,1,flag2);
//flag2 只包含了IPC_CREAT標(biāo)志, 參數(shù)nsems(這里為1)必須與原來的信號(hào)燈數(shù)目一致
arg.buf=&sem_info;
for(i=0; isem_otime!=0){ i=max_tries; init_ok=1;}
else sleep(1);
}
}
if(!init_ok)
// do some initializing, here we assume that the first process that creates the sem will
// finish initialize the sem and run semop in max_tries*1 seconds. else it will not run
// semop any more.
{
arg.val=1;
if(semctl(semid,0,SETVAL,arg)==-1) perror("semctl setval error");
}
}
else
{perror("semget error, process exit"); exit(); }
}
else //semid>=0; do some initializing
{
arg.val=1;
if(semctl(semid,0,SETVAL,arg)==-1)
perror("semctl setval error");
}
//get some information about the semaphore and the limit of semaphore in redhat8.0
arg.buf=&sem_info;
if(semctl(semid, 0, IPC_STAT, arg)==-1)
perror("semctl IPC STAT");
printf("owner's uid is %d\n", arg.buf->sem_perm.uid);
printf("owner's gid is %d\n", arg.buf->sem_perm.gid);
printf("creater's uid is %d\n", arg.buf->sem_perm.cuid);
printf("creater's gid is %d\n", arg.buf->sem_perm.cgid);

arg.__buf=&sem_info2;
if(semctl(semid,0,IPC_INFO,arg)==-1)
perror("semctl IPC_INFO");
printf("the number of entries in semaphore map is %d \n", arg.__buf->semmap);
printf("max number of semaphore identifiers is %d \n", arg.__buf->semmni);
printf("mas number of semaphores in system is %d \n", arg.__buf->semmns);
printf("the number of undo structures system wide is %d \n", arg.__buf->semmnu);
printf("max number of semaphores per semid is %d \n", arg.__buf->semmsl);
printf("max number of ops per semop call is %d \n", arg.__buf->semopm);
printf("max number of undo entries per process is %d \n", arg.__buf->semume);
printf("the sizeof of struct sem_undo is %d \n", arg.__buf->semusz);
printf("the maximum semaphore value is %d \n", arg.__buf->semvmx);

//now ask for available resource:
askfor_res.sem_num=0;
askfor_res.sem_op=-1;
askfor_res.sem_flg=SEM_UNDO;

if(semop(semid,&askfor_res,1)==-1)//ask for resource
perror("semop error");

sleep(3); //do some handling on the sharing resource here, just sleep on it 3 seconds
printf("now free the resource\n");

//now free resource
free_res.sem_num=0;
free_res.sem_op=1;
free_res.sem_flg=SEM_UNDO;

if(semop(semid,&free_res,1)==-1)//free the resource.
if(errno==EIDRM)
printf("the semaphore set was removed\n");
//you can comment out the codes below to compile a different version:
if(semctl(semid, 0, IPC_RMID)==-1)
perror("semctl IPC_RMID");
else printf("remove sem ok\n");
}

注:讀者可以嘗試一下注釋掉初始化步驟,進(jìn)程在運(yùn)行時(shí)會(huì)出現(xiàn)何種情況(進(jìn)程在申請(qǐng)資源時(shí)會(huì)睡眠),同時(shí)可以像程序結(jié)尾給出的注釋那樣,把該程序編譯成兩個(gè)不同版本。下面是本程序的運(yùn)行結(jié)果(操作系統(tǒng)redhat8.0):


owner's uid is 0
owner's gid is 0
creater's uid is 0
creater's gid is 0
the number of entries in semaphore map is 32000
max number of semaphore identifiers is 128
mas number of semaphores in system is 32000
the number of undo structures system wide is 32000
max number of semaphores per semid is 250
max number of ops per semop call is 32
max number of undo entries per process is 32
the sizeof of struct sem_undo is 20
the maximum semaphore value is 32767
now free the resource
remove sem ok

Summary:信號(hào)燈與其它進(jìn)程間通信方式有所不同,它主要用于進(jìn)程間同步。通常所說的系統(tǒng)V信號(hào)燈實(shí)際上是一個(gè)信號(hào)燈的集合,可用于多種共享資源的進(jìn)程間同步。每個(gè)信號(hào)燈都有一個(gè)值,可以用來表示當(dāng)前該信號(hào)燈代表的共享資源可用(available)數(shù)量,如果一個(gè)進(jìn)程要申請(qǐng)共享資源,那么就從信號(hào)燈值中減去要申請(qǐng)的數(shù)目,如果當(dāng)前沒有足夠的可用資源,進(jìn)程可以睡眠等待,也可以立即返回。當(dāng)進(jìn)程要申請(qǐng)多種共享資源時(shí),linux可以保證操作的原子性,即要么申請(qǐng)到所有的共享資源,要么放棄所有資源,這樣能夠保證多個(gè)進(jìn)程不會(huì)造成互鎖。Linux對(duì)信號(hào)燈有各種各樣的限制,程序中給出了輸出結(jié)果。另外,如果讀者想對(duì)信號(hào)燈作進(jìn)一步的理解,建議閱讀sem.h源代碼,該文件不長,但給出了信號(hào)燈相關(guān)的重要數(shù)據(jù)結(jié)構(gòu)。

附錄1: struct sem_array如下:


/*系統(tǒng)中的每個(gè)信號(hào)燈集對(duì)應(yīng)一個(gè)sem_array 結(jié)構(gòu) */
struct sem_array {
struct kern_ipc_perm sem_perm; /* permissions .. see ipc.h */
time_t sem_otime; /* last semop time */
time_t sem_ctime; /* last change time */
struct sem *sem_base; /* ptr to first semaphore in array */
struct sem_queue *sem_pending; /* pending operations to be processed */
struct sem_queue **sem_pending_last; /* last pending operation */
struct sem_undo *undo; /* undo requests on this array */
unsigned long sem_nsems; /* no. of semaphores in array */
};

其中,sem_queue結(jié)構(gòu)如下:


/* 系統(tǒng)中每個(gè)因?yàn)樾盘?hào)燈而睡眠的進(jìn)程,都對(duì)應(yīng)一個(gè)sem_queue結(jié)構(gòu)*/
struct sem_queue {
struct sem_queue * next; /* next entry in the queue */
struct sem_queue ** prev; /* previous entry in the queue, *(q->prev) == q */
struct task_struct* sleeper; /* this process */
struct sem_undo * undo; /* undo structure */
int pid; /* process id of requesting process */
int status; /* completion status of operation */
struct sem_array * sma; /* semaphore array for operations */
int id; /* internal sem id */
struct sembuf * sops; /* array of pending operations */
int nsops; /* number of operations */
int alter; /* operation will alter semaphore */
};

附錄2:union semun是系統(tǒng)調(diào)用semctl中的重要參數(shù):


union semun {
int val; /* value for SETVAL */
struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */
unsigned short *array; /* array for GETALL & SETALL */
struct seminfo *__buf; /* buffer for IPC_INFO */ //test!!
void *__pad;
};
struct seminfo {
int semmap;
int semmni;
int semmns;
int semmnu;
int semmsl;
int semopm;
int semume;
int semusz;
int semvmx;
int semaem;
};

參考文獻(xiàn):

[1] UNIX網(wǎng)絡(luò)編程第二卷:進(jìn)程間通信,作者:W.Richard Stevens,譯者:楊繼張,清華大學(xué)出版社。對(duì)POSIX以及系統(tǒng)V信號(hào)燈都有闡述,對(duì)Linux環(huán)境下的程序開發(fā)有極大的啟發(fā)意義。

[2] linux內(nèi)核源代碼情景分析(上),毛德操、胡希明著,浙江大學(xué)出版社,給出了系統(tǒng)V信號(hào)燈相關(guān)的源代碼分析,尤其在闡述保證操作原子性方面,以及闡述undo標(biāo)志位時(shí),討論的很深刻。

[3]GNU/Linux編程指南,第二版,Kurt Wall等著,張輝譯

[4]semget、semop、semctl手冊(cè)

關(guān)于作者:

鄭彥興,國防科大攻讀博士學(xué)位。聯(lián)系方式: mlinux@163.com

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲激情欧美激情| 亚洲在线观看免费| 一区二区三区高清视频在线观看| 国产精品综合| 欧美日韩在线看| 欧美成人资源| 女同性一区二区三区人了人一| 宅男在线国产精品| 亚洲一区欧美二区| 亚洲欧美日韩精品久久奇米色影视 | 亚洲人在线视频| 久久综合图片| 欧美国产日韩一区二区在线观看| 美女免费视频一区| 亚洲人久久久| 亚洲欧洲av一区二区| 久久久av毛片精品| 欧美日韩播放| 国产香蕉97碰碰久久人人| 亚洲国产精品第一区二区| 亚洲先锋成人| 美女图片一区二区| 亚洲精品欧美日韩| 久久er精品视频| 欧美精品激情| 国产日韩在线视频| 夜夜爽www精品| 久久免费精品视频| 亚洲免费精彩视频| 久久久久久久91| 国产精品99免费看| 亚洲福利视频二区| 欧美在线精品一区| 国产精品女主播| 国产亚洲欧美日韩在线一区 | 蜜臀av性久久久久蜜臀aⅴ| 美女脱光内衣内裤视频久久影院| 欧美经典一区二区三区| 国产亚洲亚洲| 亚洲国产综合在线| 亚洲一区二区三区精品动漫| 乱中年女人伦av一区二区| 亚洲三级观看| 久久国产福利| 国产日韩精品电影| 一区二区三区偷拍| 两个人的视频www国产精品| 亚洲乱码国产乱码精品精天堂| 久久精品国产第一区二区三区| 欧美日韩视频专区在线播放 | 一本久久综合亚洲鲁鲁五月天| 久久久久久成人| 国产在线不卡精品| 中文日韩在线| 亚洲国产网站| 女女同性精品视频| 国产精品人成在线观看免费| 日韩视频精品| 欧美激情亚洲一区| 欧美一区二区啪啪| 国产精品在线看| 欧美亚洲视频在线观看| 亚洲国产一区在线观看| 久久在线精品| 亚洲国产精品小视频| 久久综合伊人| 久久人人爽爽爽人久久久| 国产综合色一区二区三区| 久久久夜夜夜| 老司机成人在线视频| 亚洲国产成人久久综合| 亚洲成色www久久网站| 欧美成人激情在线| 一本久久a久久免费精品不卡| 亚洲美女啪啪| 国产精品永久免费| 老司机午夜精品视频| 免费在线成人av| 夜夜精品视频| 亚洲欧美日韩综合一区| 黄色一区二区三区四区| 亚洲电影在线免费观看| 欧美日韩中国免费专区在线看| 午夜电影亚洲| 久久久久国产精品麻豆ai换脸| 在线一区二区三区四区| 亚洲一区999| 国产亚洲一级| 欧美高清不卡在线| 欧美日韩亚洲网| 久久精品免视看| 欧美成人国产| 欧美一级网站| 美女网站在线免费欧美精品| aⅴ色国产欧美| 欧美亚洲自偷自偷| 99精品国产在热久久婷婷| 亚洲综合999| 亚洲黄色尤物视频| 亚洲一区在线直播| 亚洲激情视频在线| 午夜精品久久久久久99热软件| 亚洲国产另类久久精品| 亚洲免费在线电影| 日韩视频在线观看免费| 性色av一区二区怡红| 一区二区三区日韩在线观看| 久久精品青青大伊人av| 亚洲免费在线观看视频| 男人天堂欧美日韩| 久久香蕉精品| 国产日韩欧美一区二区三区在线观看| 欧美国产另类| 国产偷久久久精品专区| 亚洲精选久久| 91久久久亚洲精品| 久久精品亚洲乱码伦伦中文| 亚洲无线视频| 欧美极品欧美精品欧美视频| 久久伊人精品天天| 国产九九精品| 一区二区三区蜜桃网| 9i看片成人免费高清| 免费一级欧美片在线播放| 浪潮色综合久久天堂| 国产欧美丝祙| 亚洲欧美激情视频| 亚洲综合电影| 欧美丝袜第一区| 亚洲精品少妇30p| 亚洲理伦在线| 欧美激情欧美激情在线五月| 蜜臀av一级做a爰片久久| 激情一区二区三区| 久久久久久久高潮| 久久久蜜桃精品| 激情亚洲网站| 美女久久一区| 亚洲国产精品成人综合| 怡红院精品视频在线观看极品| 久久九九免费视频| 99视频在线精品国自产拍免费观看| 久久亚裔精品欧美| 欧美专区在线播放| 国产日本精品| 久久国产精品一区二区三区| 久久久久久9| 伊大人香蕉综合8在线视| 久久午夜精品一区二区| 欧美成人午夜剧场免费观看| 在线免费观看一区二区三区| 亚洲综合欧美| 久久免费国产| 亚洲高清免费视频| 亚洲欧洲精品一区二区三区不卡| 免费欧美在线视频| 亚洲欧洲日本mm| 亚洲午夜一二三区视频| 国产精品久久久久久久久久三级| 亚洲一区二区欧美| 久久久人成影片一区二区三区| 韩国v欧美v日本v亚洲v| 鲁大师影院一区二区三区| 亚洲国产影院| 先锋资源久久| 亚洲电影激情视频网站| 欧美不卡视频| 亚洲香蕉伊综合在人在线视看| 久久精品免费电影| 亚洲免费观看高清在线观看 | 亚洲欧美日韩国产精品| 久久夜色精品国产欧美乱| 亚洲欧洲综合另类在线| 欧美视频一区二区在线观看| 午夜精品久久久久久久蜜桃app | 欧美黄色aaaa| 亚洲欧美怡红院| 亚洲国产精品一区二区第一页| 欧美精品999| 欧美一区二区三区啪啪| 亚洲欧洲日夜超级视频| 久久国内精品视频| 夜夜嗨av一区二区三区免费区| 国产在线视频不卡二| 欧美日韩在线三区| 久久综合国产精品台湾中文娱乐网| 日韩午夜在线电影| 欧美不卡视频一区| 欧美中文在线观看| 国产精品99久久不卡二区| 原创国产精品91| 国产欧美日韩亚洲| 欧美日韩一区在线视频| 欧美~级网站不卡| 久久九九久久九九| 亚洲欧美日韩国产精品| 中国日韩欧美久久久久久久久| 欧美国产高清| 欧美国产在线电影| 免费久久久一本精品久久区|