www.pudn.com > pthread_examples.rar > semop.c
#include#include #include #define SEM_PATH "/home/share/jinbq/pthread_examples/semop/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 { 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; }; */ union semun arg; //union semun: 请参考附录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标志, 参数nsems(这里为1)必须与原来的信号灯数目一致 arg.buf = &sem_info; for(i=0; i sem_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"); }