structsemid_ds { structipc_permsem_perm;// operation permission struct structsem *sem_base;// ptr to first semaphore in set unsignedshort sem_nsems; // numbers of semaphore in set time_t sem_otime; // last semop time time_t sem_ctime; // last change time };
intmain(int argc, char *argv[]) { key_t keyid; int sigid; int nsems, semflg; nsems = 1; semflg = IPC_CREAT|0666;
// below 4 lines code not necessary, just show the PATHNANE -> dev & inode, // then combine with proj_id to calculate the keyid (ftok work principle) structstatstat_info; stat(PATHNAME, &stat_info); printf("dev:%lx\n", stat_info.st_dev); printf("inode:%lx\n", stat_info.st_ino);
// monitor the semphore usage status while(1) { if(semop(sigid, &sbuf, 1) == 0)// use up!!! printf("resources have been exhausted\n"); sleep(3); } return0; }
$ ./sem_server key is 3040001 create semaphore ok initial the semphore ok
可以看到信号量创建并初始化成功,进入监视状态,在另一个shell中运行客户端程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
$ ./sem_client key is 3040001 get the semaphore ok p -->Total unused resources:2 p -->Total unused resources:1 p -->Total unused resources:0 v -->Total unused resources:1 s -->Total unused resources:1 q
$ ./sem_server key is 3040001 create semaphore ok initial the semphore ok resources have been exhausted resources have been exhausted resources have been exhausted
// get some information about the semaphore and the limit of semaphore in Linux 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, SEM_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);//o); printf("mas number of semaphore 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 semaphore 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 size 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) perror("semop error");
sleep(3); printf("now free the resource\n");
// now free resource free_res.sem_num = 0; // resources num free_res.sem_op = 1; free_res.sem_flg = SEM_UNDO; if(semop(semid, &free_res, 1) == -1) if(errno == EIDRM) printf("the semaphore set was removed\n");
$ ./sem_app owner's uid is 1000 owner's gid is 1000 creater's uid is 1000 creater's gid is 1000 the number of entries in semaphore map is 1024000000 max number of semaphore identifiers is 32000 mas number of semaphore in system is 1024000000 the number of undo structures system wide is 1024000000 max number of semaphore per semid is 32000 max number of ops per semop call is 500 max number of undo entries per process is 500 the size of struct sem_undo is 1 the maximum semaphore value is 32767 now free the resource remove sem okt