
文章插图
实际上,这种解决方法也是基于这样一个假定:第一个创建信号灯的进程必须调用semop,这样sem_otime才能变为非零值 。另外,因为第一个进程可能不调用semop,或者semop操作需要很长时间,第二个进程可能无限期等待下去,或者等待很长时间 。
7. 信号灯应用实例本实例有两个目的:1、获取各种信号灯信息;2、利用信号灯实现共享资源的申请和释放 。并在程序中给出了详细注释 。
#include <stdio.h>#include <sys/sem.h>#include <errno.h>#include <unistd.h>#include <stdlib.h>#define SEM_PATH "/unix/my_sem"#define max_tries 10 #ifndef IPC_INFO#define IPC_INFO 3/* see ipcs */#endif int gi_semid;const int gi_semcnt = 1; 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;};int main(){int i_flag_create, i_flag_get, i_key, i, i_init_ok, i_tmperrno;struct semid_ds semid_ds_var;struct seminfo seminfo_var;union semun semun_arg;struct sembuf sembuf_ask, sembuf_free;i_flag_create = IPC_CREAT | IPC_EXCL | 00666;i_flag_get = IPC_CREAT | 00666;i_key = ftok( SEM_PATH, 'a' );//error handling for ftok here;i_init_ok = 0;gi_semid = semget( i_key, gi_semcnt, i_flag_create );//create a semaphore set that only includes one semaphore.if( gi_semid < 0 ){i_tmperrno = errno;perror( "semget" );if( i_tmperrno == EEXIST )//errno is undefined after a successful library call( including perror call)//so it is saved in i_tmperrno.{gi_semid = semget( i_key, gi_semcnt, i_flag_get );// i_flag_get 只包含了IPC_CREAT标志, 参数nsems(这里为1)// 必须与原来的信号灯数目一致semun_arg.buf = &semid_ds_var;for ( i = 0; i < max_tries; i++ ){printf( "semctl IPC_STAT, to solve compete: %d n", i );if ( semctl( gi_semid, 0, IPC_STAT, semun_arg ) == -1 ){perror( "semctl error" );i = max_tries;}else{if( semun_arg.buf->sem_otime != 0 )// the create process already initialized the semaphore{i = max_tries;i_init_ok = 1;}elsesleep(1);}} // for(i=0; i<max_tries; i++)if( !i_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.{printf( "semctl SETVALn" );semun_arg.val = 1;if ( semctl( gi_semid, 0, SETVAL, semun_arg ) == -1 )perror( "semctl SETVAL error" );} // if(!i_init_ok)} // if(i_tmperrno==EEXIST)else{perror("semget error, process exit");exit( 1 );}}else //gi_semid>=0; do some initializing{printf( "create semaphore success, initialize itn" );semun_arg.val = 1;if ( semctl( gi_semid, 0, SETVAL, semun_arg ) == -1 )perror( "semctl SETVAL error" );}//get some information about the semaphore and the limit of semaphore in redhat8.0semun_arg.buf=&semid_ds_var;if( semctl( gi_semid, 0, IPC_STAT, semun_arg ) == -1 )perror("semctl IPC STAT");printf( "owner's uid is %dn", semun_arg.buf->sem_perm.uid );printf( "owner's gid is %dn", semun_arg.buf->sem_perm.gid );printf( "creater's uid is %dn", semun_arg.buf->sem_perm.cuid );printf( "creater's gid is %dn", semun_arg.buf->sem_perm.cgid );semun_arg.__buf = &seminfo_var;if( semctl( gi_semid, 0, IPC_INFO, semun_arg ) == -1 )perror( "semctl IPC_INFO" );printf( "the number of entries in semaphore map is %d n", semun_arg.__buf->semmap );printf( "max number of semaphore identifiers is %d n", semun_arg.__buf->semmni );printf( "mas number of semaphores in system is %d n", semun_arg.__buf->semmns );printf( "the number of undo structures system wide is %d n", semun_arg.__buf->semmnu );printf( "max number of semaphores per gi_semid is %d n", semun_arg.__buf->semmsl );printf( "max number of ops per semop call is %d n", semun_arg.__buf->semopm );printf( "max number of undo entries per process is %d n", semun_arg.__buf->semume );printf( "the sizeof of struct sem_undo is %d n", semun_arg.__buf->semusz );printf( "the maximum semaphore value is %d n", semun_arg.__buf->semvmx );// print sem_otimesemun_arg.buf = &semid_ds_var;if ( semctl( gi_semid, 0, IPC_STAT, semun_arg ) == -1 ){perror( "semctl error" );i = max_tries;}else{printf( "before semop, semun_arg.buf->sem_otime: %lun", semun_arg.buf->sem_otime );}//now ask for available resource:printf( "now ask the resourcen" );sembuf_ask.sem_num = 0;sembuf_ask.sem_op = -1;sembuf_ask.sem_flg = SEM_UNDO;if( semop( gi_semid, &sembuf_ask, 1 ) == -1 )//ask for resourceperror("semop error");printf( "ask the resource successn" );// print sem_otimesemun_arg.buf = &semid_ds_var;if ( semctl( gi_semid, 0, IPC_STAT, semun_arg ) == -1 ){perror( "semctl error" );i = max_tries;}else{printf( "after semop, semun_arg.buf->sem_otime: %lun", semun_arg.buf->sem_otime );}sleep(5);//do some handling on the sharing resource here, just sleep on it 3 secondsprintf( "now free the resourcen" );//now free resourcesembuf_free.sem_num = 0;sembuf_free.sem_op = 1;sembuf_free.sem_flg = SEM_UNDO;if ( semop( gi_semid, &sembuf_free, 1 ) == -1 )//free the resource.if( errno == EIDRM )printf( "the semaphore set has been removedn" );//you can comment out the codes below to compile a different version:if( semctl( gi_semid, 0, IPC_RMID ) == -1 )perror( "semctl IPC_RMID" );elseprintf("remove sem okn");return 0;}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 红茶时间越久越好吗,普洱茶生茶判别
- 神舟十一号飞船的发射时间 神舟十号飞船发射火箭返回时间
- 凤凰山ufo神秘事件 凤凰山UFO事件
- 立冬下雨好还是天晴好?
- 一天最佳三个运动时间是何时?
- 空间站|天舟三号从空间站后端绕前端对接:将迎接天舟四号、神舟十四号载人飞船
- 面试官:知道时间轮算法吗?在Netty和Kafka中如何应用的?
- 灵异真实故事民间 灵异民间故事
- 启元世界:打造AI决策智能体,用小样本实现10的26次方复杂空间决策
- 2021年中国空间站计划 我国空间站将在2022年前后建成并运营
