?? 多進(jìn)程編程.htm
字號:
for (i=0;i<20;i++)
signal(i,cleanup);
shmid=shmget(SHMKEY,128*K,0777|IPC_CREAT);
addr1=shmat(shmid,0,0);
addr2=shmat(shmid,0,0);
printf("addr1 0x%x addr2 0x%x\n",addr1,addr2);
pint=(int*)addr1;
for (i=0;i<256;i++)
*pint++=i;
pint=(int*)addr1;
*pint=256;
pint=(int*)addr2;
for (i=0;i<256;i++)
printf("index %d\tvalue%d\n",i,*pint++);
shmdt(addr1);
shmdt(addr2);
pause();
}
21.semctl()
功能:信號量控制操作.
語法:#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semctl(semid,memnum,cmd,arg)
int semid,semnum,cmd;
union semun {
int val;
struct semid_ds *buf;
ushort *array;
}arg;
說明:本系統(tǒng)調(diào)用提供了一個(gè)信號量控制操作,操作行為由cmd定義,這
些命令是對由semid和semnum指定的信號量做操作的.每個(gè)命令都
要求有相應(yīng)的權(quán)限級別:
. GETVAL:返回semval的值,要求有讀權(quán)限.
. SETVAL:設(shè)置semval的值到arg.val上.此命令成功執(zhí)行后,
semadj的值對應(yīng)的所有進(jìn)程的信號量全部被清除,要求有修
改權(quán)限.
. GETPID:返回sempid的值,要求有讀權(quán)限.
. GETNCNT:返回semncnt的值,要求有讀權(quán)限.
. GETZCNT:返回semzcnt的值,要求有讀權(quán)限.
以下命令在一組信號量中的各個(gè)semval上操作:
. GETALL:返回每個(gè)semval的值,同時(shí)將各個(gè)值放入由arg.array
指向的數(shù)組中.當(dāng)此命令成功執(zhí)行后,semadj的值對應(yīng)的所有
進(jìn)程的信號量全部被清除,要求有修改權(quán)限.
. SETALL:根據(jù)由arg.array指向的數(shù)組設(shè)置各個(gè)semval值.當(dāng)此
命令成功執(zhí)行后,semadj的值對應(yīng)的所有進(jìn)程的信號量全部
被清除,要求有修改權(quán)限.
以下命令在任何情況下都是有效的:
. IPC_STAT:將與semid相關(guān)的數(shù)據(jù)結(jié)構(gòu)的各個(gè)成員的值放入由
arg.buf指向的結(jié)構(gòu)中.要求有讀權(quán)限.
. IPC_SET:設(shè)置semid相關(guān)數(shù)據(jù)結(jié)構(gòu)的如下成員,設(shè)置數(shù)據(jù)從
arg.buf指向的結(jié)構(gòu)中讀取:
sem_perm.uid
sem_perm.gid
sem_perm.mode
本命令只能由有效UID等于sem_perm.cuid或sem_perm.uid的
進(jìn)程或有效UID有合適權(quán)限的進(jìn)程操作.
. IPC_RMID:刪除由semid指定的信號量標(biāo)識符和相關(guān)的一組信號
量及數(shù)據(jù)結(jié)構(gòu).本命令只能由有效UID等于sem_perm.cuid或
sem_perm.uid的進(jìn)程或有效UID有合適權(quán)限的進(jìn)程操作.
返回值:若調(diào)用成功,則根據(jù)cmd返回以下值:
GETVAL:semval的值.
GETPID:sempid的值.
GETNCNT:semncnt的值.
GETZCNT:semzcnt的值.
其他:0.
若調(diào)用失敗則返回-1.
22.semget()
功能:取得一組信號量.
語法:#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget(key,nsems,semflg)
key_t key;
int nsems,semflg;
說明:返回和key相關(guān)的信號量標(biāo)識符.
若以下事實(shí)成立,則與信號量標(biāo)識符,與之相關(guān)的semid_ds數(shù)據(jù)結(jié)
構(gòu)及一組nsems信號量將被創(chuàng)建:
. key等于IPC_PRIVATE.
. 系統(tǒng)內(nèi)還沒有與key相關(guān)的信號量,同時(shí)(semflg&IPC_CREAT)
為真.
創(chuàng)建時(shí)新的信號量相關(guān)的semid_ds數(shù)據(jù)結(jié)構(gòu)被初始化如下:
. 在操作權(quán)限結(jié)構(gòu),sem_perm.cuid和sem_perm.uid設(shè)置等于調(diào)用
進(jìn)程的有效UID.
. 在操作權(quán)限結(jié)構(gòu),sem_perm.cgid和sem_perm.gid設(shè)置等于調(diào)用
進(jìn)程的有效GID.
. 訪問權(quán)限比特位sem_perm.mode設(shè)置等于semflg的訪問權(quán)限比
特位.
. sem_otime設(shè)置等于0,sem_ctime設(shè)置等于當(dāng)前系統(tǒng)時(shí)間.
返回值:若調(diào)用成功,則返回一非0值,稱為信號量標(biāo)識符;否則返回-1.
23.semop()
功能:信號量操作.
語法:#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semop(semid,sops,nsops)
int semid;
struct sembuf *sops;
unsigned nsops;
說明:本系統(tǒng)調(diào)用用于執(zhí)行用戶定義的在一組信號量上操作的行為集合.
該組信號量與semid相關(guān).
參數(shù)sops為一個(gè)用戶定義的信號量操作結(jié)構(gòu)數(shù)組指針.
參數(shù)nsops為該數(shù)組的元素個(gè)數(shù).
數(shù)組的每個(gè)元素結(jié)構(gòu)包括如下成員:
sem_num; /* 信號量數(shù) */
sem_op; /* 信號量操作 */
sem_flg; /* 操作標(biāo)志 */
由本系統(tǒng)調(diào)用定義的每個(gè)信號量操作是針對由semid和sem_num指
定的信號量的.變量sem_op指定三種信號量操作的一種:
. 若sem_op為一負(fù)數(shù)并且調(diào)用進(jìn)程具有修改權(quán)限,則下列情況之
一將會發(fā)生:
* 若semval不小于sem_op的絕對值,則sem_op的絕對值被減去
semval的值.若(semflg&SEM_UNDO)為真則sem_op的絕對值加
上調(diào)用進(jìn)程指定的信號量的semadj值.
* 若semval小于sem_op的絕對值同時(shí)(semflg&IPC_NOWAIT)為
真,則本調(diào)用立即返回.
* 若semval小于sem_op的絕對值同時(shí)(semflg&IPC_NOWAIT)為
假,則本系統(tǒng)調(diào)用將增加指定信號量相關(guān)的semncnt值(加一),
將調(diào)用進(jìn)程掛起直到下列條件之一被滿足:
(1).semval值變成不小于sem_op的絕對值.當(dāng)這種情況發(fā)
生時(shí),指定的信號量相關(guān)的semncnt減一,若
(semflg&SEM_UNDO)為真則sem_op的絕對值加上調(diào)用
進(jìn)程指定信號量的semadj值.
(2).調(diào)用進(jìn)程等待的semid已被系統(tǒng)刪除.
(3).調(diào)用進(jìn)程捕俘到信號,此時(shí),指定信號量的semncnt值
減一,調(diào)用進(jìn)程執(zhí)行中斷服務(wù)程序.
. 若sem_op為一正值,同時(shí)調(diào)用進(jìn)程具有修改權(quán)限,sem_op的值加
上semval的值,若(semflg&SEM_UNDO)為真,則sem_op減去調(diào)用
進(jìn)程指定信號量的semadj值.
. 若sem_op為0,同時(shí)調(diào)用進(jìn)程具有讀權(quán)限,下列情況之一將會發(fā)
生:
* 若semval為0,本系統(tǒng)調(diào)用立即返回.
* 若semval不等于0且(semflg&IPC_NOWAIT)為真,本系統(tǒng)調(diào)用
立即返回.
* 若semval不等于0且(semflg&IPC_NOWAIT)為假,本系統(tǒng)調(diào)用
將把指定信號量的
semzcnt值加一,將調(diào)用進(jìn)程掛起直到下列情況之一發(fā)生:
(1).semval值變?yōu)?時(shí),指定信號量的semzcnt值減一.
(2).調(diào)用進(jìn)程等待的semid已被系統(tǒng)刪除.
(3).調(diào)用進(jìn)程捕俘到信號,此時(shí),指定信號量的semncnt值
減一,調(diào)用進(jìn)程執(zhí)行中斷服務(wù)程序.
返回值:調(diào)用成功則返回0,否則返回-1.
例子:本例將包括上述信號量操作的所有系統(tǒng)調(diào)用:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#define SEMKEY 75
int semid;
unsigned int count;
/*在文件sys/sem.h中定義的sembuf結(jié)構(gòu)
* struct sembuf {
* unsigned short sem_num;
* short sem_op;
* short sem_flg;
* }*/
struct sembuf psembuf,vsembuf; /*P和V操作*/
cleanup()
{
semctl(semid,2,IPC_RMID,0);
exit(0);
}
main(argc,argv)
int argc;
char *argv[];
{
int i,first,second;
short initarray[2],outarray[2];
extern cleanup();
if (argc==1) {
for (i=0;i<20;i++)
signal(i,clearup);
semid=semget(SEMKEY,2,0777|IPC_CREAT);
initarray[0]=initarray[1]=1;
semctl(semid,2,SETALL,initarray);
semctl(semid,2,GETALL,outarray);
printf("sem init vals %d%d \n",
outarray[0],outarray[1]);
pause(); /*睡眠到被一軟件中斷信號喚醒*/
}
else if (argv[1][0]=='a') {
first=0;
second=1;
}
else {
first=1;
second=0;
}
semid=semget(SEMKEY,2,0777);
psembuf.sem_op=-1;
psembuf.sem_flg=SEM_UNDO;
vsembuf.sem_op=1;
vsembuf.sem_flg=SEM_UNDO;
for (count=0;;xcount++) {
psembuf.sem_num=first;
semop(semid,&psembuf,1);
psembuf.sem_num=second;
semop(semid,&psembuf,1);
printf("proc %d count %d\n",getpid(),count);
vsembuf.sem_num=second;
semop(semid,&vsembuf,1);
vsembuf.sem_num=first;
semop(semid,&vsembuf,1);
}
}
24.sdenter()
功能:共享數(shù)據(jù)段同步訪問,加鎖.
語法:#include <sys/sd.h>
int sdenter(addr,flags)
char *addr;
int flags;
說明:用于指示調(diào)用進(jìn)程即將可以訪問共享數(shù)據(jù)段中的內(nèi)容.
參數(shù)addr為將一個(gè)sdget()調(diào)用的有效返回碼.
所執(zhí)行的動(dòng)作取決于flags的值:
. SD_NOWAIT:若另一個(gè)進(jìn)程已對指定的段調(diào)用本系統(tǒng)調(diào)用且還沒
有調(diào)用sdleave(),并且該段并非用SD_UNLOCK標(biāo)志創(chuàng)建,則調(diào)
用進(jìn)程不是等待該段空閑而是立即返回錯(cuò)誤碼.
. SD_WRITE:指示調(diào)用進(jìn)程希望向共享數(shù)據(jù)段寫數(shù)據(jù).此時(shí),另一
個(gè)進(jìn)程用SD_RDONLY標(biāo)志聯(lián)接該共享數(shù)據(jù)段則不被允許.
返回值:調(diào)用成功則返回0,否則返回-1.
25.sdleave()
功能:共享數(shù)據(jù)段同步訪問,解鎖.
語法:#include <sys/sd.h>
int sdleave(addr,flags)
char *addr;
說明:用于指示調(diào)用進(jìn)程已完成修改共享數(shù)據(jù)段中的內(nèi)容.
返回值:調(diào)用成功則返回0,否則返回-1.
26.sdget()
功能:聯(lián)接共享數(shù)據(jù)段到調(diào)用進(jìn)程的數(shù)據(jù)空間中.
語法:#include <sys/sd.h>
char *sdget(path,flags,size.mode)
char *path;
int flags;
long size;
int mode;
說明:本系統(tǒng)調(diào)用將共享數(shù)據(jù)段聯(lián)接到調(diào)用進(jìn)程的數(shù)據(jù)段中,具體動(dòng)作
由flags的值定義:
. SD_RDONLY:聯(lián)接的段為只讀的.
. SD_WRITE:聯(lián)接的段為可讀寫的.
. SD_CREAT:若由path命名的段存在且不在使用中,本標(biāo)志的作用
同早先創(chuàng)建一個(gè)段相同,否則,該段根據(jù)size和mode的值進(jìn)程
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -