?? 信號燈.txt
字號:
// 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");
}
注:讀者可以嘗試一下注釋掉初始化步驟,進程在運行時會出現(xiàn)何種情況(進程在申請資源時會睡眠),同時可以像程序結(jié)尾給出的注釋那樣,把該程序編譯成兩個不同版本。下面是本程序的運行結(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:信號燈與其它進程間通信方式有所不同,它主要用于進程間同步。通常所說的系統(tǒng)V信號燈實際上是一個信號燈的集合,可用于多種共享資源的進程間同步。每個信號燈都有一個值,可以用來表示當前該信號燈代表的共享資源可用(available)數(shù)量,如果一個進程要申請共享資源,那么就從信號燈值中減去要申請的數(shù)目,如果當前沒有足夠的可用資源,進程可以睡眠等待,也可以立即返回。當進程要申請多種共享資源時,linux可以保證操作的原子性,即要么申請到所有的共享資源,要么放棄所有資源,這樣能夠保證多個進程不會造成互鎖。Linux對信號燈有各種各樣的限制,程序中給出了輸出結(jié)果。另外,如果讀者想對信號燈作進一步的理解,建議閱讀sem.h源代碼,該文件不長,但給出了信號燈相關(guān)的重要數(shù)據(jù)結(jié)構(gòu)。
附錄1: struct sem_array如下:
/*系統(tǒng)中的每個信號燈集對應(yīng)一個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)中每個因為信號燈而睡眠的進程,都對應(yīng)一個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;
};
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -