| | exit(); | | } | +------------------------------------------------------------+ 11.8. () " - ", 340 . , . - , - , . , - , . msgctl , . : msgctl(id,cmd,mstatbuf) id - , cmd - , mstatbuf - - , - . . , 11.8. - cleanup . SIGKILL, , . () - , . 11.2.2  ( ) - . . shmget - , shmat , shmdt , shmctl , . , - , . - , ; - - - . shmget: shmid = shmget(key,size,flag); size - . key : - , . IPC_CREAT, , - allocreg ( 6.5.2). , - ( 11.9) , - , . - ( ..) , - . 341 , , . , - , ( ). - - - - +----------+ +--------------+ +---------+ | ----+----+ | | +----+---- | +----------+ +|->+--------------+<----+ +---------+ | ----+---+| | | +---+---- | +----------+ | +--------------+<----+| +---------+ | ----+--+ | | | +|---+---- | +----------+ | | +--------------+ | +---------+ | - | | | | | | | | | - | | +->+--------------+ | +---------+ | - | | | | | | | | - | +--->+--------------+<-----+ +---------+ | - | | | ( | | | - | +--------------+ shmat) +---------+ | - | | - | | | | - | | - | +---------+ | - | +--------------+ | - | | - | | - | +----------+ +---------+ 11.9. , shmat: virtaddr = shmat(id,addr,flags); id, shmget, - , addr , - , (flags) , - - . , virtaddr, - , - , . shmat ( 11.10). ; 0, . ; , . , , brk, , ; - , - . - , - . , , , - . - 342 +------------------------------------------------------------+ | shmat /* */ | | : (1) | | | | (2) | | | | (3) | | : , | | | | { | | , - | | ; | | ( ) | | { | | - | | ; | | , | | ; | | } | | /* , | | * */ | | : | | ; | | | | ( attachreg); | | ( ) | | | | ( growreg); | | ( | | ); | | } | +------------------------------------------------------------+ 11.10. attachreg. , - , , - growreg, , - . - shmdt(addr) addr - , shmat. , , - , - - , . , detachreg ( 6.5.7). - , , , . , 11.11. 343 , 128 - . "" , "" - . 11.12 , ( 64 , , - ); , , . "" (pause), - ; , . shmctl: shmctl(id,cmd,shmstatbuf); id , cmd , shmstatbuf , . - , . - , : , , freereg ( 6.5.6). - - ( 0), , , - . , , , . - , . , - . 11.2.3  - , - ( ). , , - creat . , creat , , . , , , , . , - , : P V (. [Dijkstra 68]). P , 0, V - ( , ). , - P V. , , , , 1. ; , 344 . - , ; , . V UNIX : * , * , , * , , * , , 0. semget, - semctl, - semop. +------------------------------------------------------------+ | #include | | #include | | #include | | #define SHMKEY 75 | | #define K 1024 | | int shmid; | | | | main() | | { | | int i, *pint; | | char *addr1, *addr2; | | extern char *shmat(); | | extern cleanup(); | | | | 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 Ox%x addr2 Ox%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++); | | | | pause(); | | } | | | | cleanup() | | { | | shmctl(shmid,IPC_RMID,0); | | exit(); | | } | +------------------------------------------------------------+ 11.11. 345 +-----------------------------------------------------+ | #include | | #include | | #include | | | | #define SHMKEY 75 | | #define K 1024 | | int shmid; | | | | main() | | { | | int i, *pint; | | char *addr; | | extern char *shmat(); | | | | shmid = shmget(SHMKEY,64*K,0777); | | | | addr = shmat(shmid,0,0); | | pint = (int *) addr; | | | | while (*pint == 0) | | ; | | for (i = 0; i < 256, i++) | | printf("%d\n",*pint++); | | } | +-----------------------------------------------------+ 11.12. +-------+ | | +---+---+---+---+---+---+---+ | +------->| 0 | 1 | 2 | 3 | 4 | 5 | 6 | | | +---+---+---+---+---+---+---+ +-------+ | | +---+---+---+ | +------->| 0 | 1 | 2 | | | +---+---+---+ +-------+ | | +---+ | +------->| 0 | | | +---+ +-------+ | | +---+---+---+ | +------->| 0 | 1 | 2 | | | +---+---+---+ +-------+ | - | | - | | - | | - | | - | +-------+ 11.13. , 346 semget: id = semget(key,count,flag); key, flag id , - ( ). - , - count ( 11.13). - , semop semctl. - semget 11.14, , . semop: oldval = semop(id,oplist,count); id - , semget, oplist - , count - . oldval , +------------------------------------------------------------+ | #include | | #include | | #include | | | | #define SEMKEY 75 | | int semid; | | unsigned int count; | | /* sembuf sys/sem.h | | * struct sembuf { | | * unsigned shortsem_num; | | * short sem_op; | | * short sem_flg; | | }; */ | | struct sembuf psembuf,vsembuf; /* P V */| | | | 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,cleanup); | | semid = semget(SEMKEY,2,0777|IPC_CREAT); | | initarray[0] = initarray[1] = 1; | | semctl(semid,2,SETALL,initarray); | | semctl(semid,2,GETALL,outarray); | | printf(" %d %d\n", | | outarray[0],outarray[1]); | | pause(); /* */ | | } | | | | /* */ | +------------------------------------------------------------+ 11.14. 347 . - : * , , , * , * . +------------------------------------------------------------+ | 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; ; count++) | | { | | psembuf.sem_num = first; | | semop(semid,&psembuf,1); | | psembuf.sem_num = second; | | semop(semid,&psembuf,1); | | printf(" %d %d\n",getpid(),count); | | vsembuf.sem_num = second; | | semop(semid,&vsembuf,1); | | vsembuf.sem_num = first; | | semop(semid,&vsembuf,1); | | } | | } | | | | cleanup() | | { | | semctl(semid,2,IPC_RMID,0); | | exit(); | | } | +------------------------------------------------------------+ 11.14. () oplist , - ( 11.15). , . - , , - . - , 348 +------------------------------------------------------------+ | semop /* */ | | : (1) | | (2) | | (3) | | : | | { | | ; | | start: - | | ; | | - | | ; | | | | ( ) | | { | | ( ) | | { | | ; | | ( UNDO)| | | | ; | | , | | ; | | } | | ( -| | ) | | { | | ( + >= 0) | | { | | - | | ; | | ( UNDO ) | | - | | ; | | ( 0) | | /* - | | * */ | +------------------------------------------------------------+ 11.15. , . , - - . . , , . 0, : 0, ; , , , "". , ( ) . - 0, , - . , , - . - , , ; , - , . 349 +------------------------------------------------------------+ | | | , -| | ; | | ; | | } | | | | - | | ( - | | ); | | ( ) | | ; | | ( , - | | ); | | start; /* | | * * / | | } | | /* */| | { | | ( ) | | { | | | | - | | ( | | ); | | ( ) | | ; | | ( , | | ); | | start; /* */ | | } | | } | | } /* */ | | /* */ | | , -| | | | ; | | , | | semop; | | } | +------------------------------------------------------------+ 11.15. () , 11.14, , ( a.out) - : a.out & a.out a & a.out b & , - , 1. - pause - , (cleanup). - 'a' (A) : 0, 1, 0 1. , - 350 0, , , ( ). - 1 - , A , - 1 0. 'b' (B) 0 1 , - A. A B , , A 0 1, B 1 0. , . , . , - . : struct sembuf psembuf[2]; psembuf[0].sem_num = 0; psembuf[1].sem_num = 1; psembuf[0].sem_op = -1; psembuf[1].sem_op = -1; semop(semid,psembuf,2); Psembuf - , 0 1. - , - . , , 0 1, 1 0, , , . IPC_NOWAIT semop : , - , , 0, IPC_NOWAIT , . , , . , - , , . , , . , , kill, , - . , , - , , , . - , semop SEM_UNDO; , , . , - . - , ( 11.16). - - , . , - semop SEM_UNDO. - - 351 +------+ | - | | - | | - | | - | +----------+ +----------+ +----------+ +------+ || || || | +-->| +-->| +-->| | +------+ | | | | | | | | +----------+ +----------+ +----------+ | | +----------+ +------+ || | +-->| | +------+ | | | - | +----------+ | - | | - | | - | +------+ 11.16. ,