{
semopts.val=init_val[index];//根据init_val数组中的值对各个信号量进行初始化
semctl(sid,index,SETVAL,semopts);
}
return(sid);
}
/*打开信号量函数*/
intopensem(constchar*pathname,intproj_id)
{
key_tmsgkey;
intsid;
if((msgkey=ftok(pathname,proj_id))==-1)
{
perror(”ftokerror!
\n");
exit
(1);
return—1;
}
if((sid=semget(msgkey,0,IPC_CREAT|0666))==—1)
{
perror(”semgetcallfailed。
\n”);
exit
(1);
return-1;
}
return(sid);
}
/*P操作函数*/
intsem_p(intsemid,intindex)
{
structsembufbuf={0,-1,IPC_NOWAIT};
if(index<0)
{
perror("indexofarraycannotequalsaminusvalue!
");
exit
(1);
return(-1);
}
buf.sem_num=index;
if(semop(semid,&buf,1)==—1)
{
perror(”awrongoperationtosemaphoreoccurred!
”);
exit
(1);
return-1;
}
return0;
}
/*V操作函数*/
intsem_v(intsemid,intindex)
{
structsembufbuf={0,+1,IPC_NOWAIT};
if(index〈0)
{
perror("indexofarraycannotequalsaminusvalue!
");
exit
(1);
return(-1);
}
buf。
sem_num=index;
if(semop(semid,&buf,1)==-1)
{
perror("awrongoperationtosemaphoreoccurred!
”);
exit
(1);
return(-1);
}
return0;
}
/*等待信号量为1函数*/
intwait_sem(intsemid,intindex)
{
while(semctl(semid,index,GETVAL,0)==0)
{
usleep(10000);
}
return1;
}
/*删除信号集函数*/
intdelete_sem(intsemid)
{
return(semctl(semid,0,IPC_RMID));
}
/*获取指信号量的值*/
intget_sem_val(intsemid,intindex)
{
returnsemctl(semid,index,GETVAL,0);
}
/*我的随机数生成器*/
intmy_random()
{
usleep(1000000);//延时函数,延时1秒,以便于生成不同的随机数
srand((unsigned)time(NULL));//初始化随机数生成器
return(rand());//调用随机数生成器生成并返回随机数
}
/*获取当前系统时间并靠右输出*/
voidprint_time()
{
time_tnow;//实例化time_t结构
structtm*timenow;//实例化tm结构指针
time(&now);//time函数读取现在的时间(国际标准时间非北京时间),然后传值给now
timenow=localtime(&now);//localtime函数把从time取得的时间now换算成你电脑中的时间(就是你设置的地区)
printf(”Time:
%s\n”,asctime(timenow));//asctime函数把时间转换成字符,通过printf()函数靠右输出
}
/*顾客取票函数,取票成功,返回1,失败返回-1,,由于没有空座,顾客选择离开则返回0*/
intget_ticket(intsemid,charidentifyLabel,int*ticket,int*flag)
{
intwait_num=0;
switch(identifyLabel)
{
case’A':
if(get_sem_val(semid,INDEX_SIGNAL_SEAT)==0)
{
if((wait_num=my_random()%10)〈5)
return0;//返回0表示顾客选择离开
printf("目前没有空座位,但该顾客选择了等待。
\n\n");
}
if(get_sem_val(semid,INDEX_SIGNAL_A)>0)//检查,如果有空窗口,则直接取票,不用判断座位
{
*flag=0;//将标志为设为0,标示没有顾客在等待,不用排队
gotogoto_A;//跳转到直接取票
}
if(wait_sem(semid,INDEX_SIGNAL_SEAT))//如果没有空座,则等待空座
sem_p(semid,INDEX_SIGNAL_SEAT);
goto_A:
if(wait_sem(semid,INDEX_MUTEX))//等待操作信号量释放
sem_p(semid,INDEX_MUTEX);//锁定操作信号量
*ticket=get_sem_val(semid,INDEX_SIGNAL_CUSTOMER)+1;//分配票号(票号是根据当天的总顾客数排的)
wait_num=(signal_seat—get_sem_val(semid,INDEX_SIGNAL_SEAT))-1;//获取当前等待的人数
printf(”号码:
A%03d,”,*ticket);
if(wait_num==0||*flag==0)
{
printf(”当前没有顾客正在等待。
\t");//wait_num大于等于0或者flag大于0,表示当前无人等待
print_time();
}
else
{
printf(”有%d位顾客正在等待。
\t”,wait_num);
print_time();
}
printf(”顾客A%03d正在等待办理业务。
\t”,*ticket);
print_time();
if(sem_v(semid,INDEX_SIGNAL_CUSTOMER)!
=0)//记录目前办理过业务和等待办理业务的顾客总数
{
printf("对不起,V操作失败!
”);
exit
(1);
return—1;
}
sem_v(semid,INDEX_MUTEX);//释放控制进程访问资源的信号量
break;
case’B':
if(get_sem_val(semid,INDEX_SIGNAL_SEAT)==0)
{
if((wait_num=my_random()%10)〈5)
return0;//返回0表示顾客选择离开
printf(”目前没有空座位,但该顾客选择了等待。
\n\n”);
}
if(get_sem_val(semid,INDEX_SIGNAL_B)>0)//检查,如果有空窗口,则直接取票,不用判断座位
{
*flag=0;//将标志为设为0,标示没有顾客在等待,不用排队
gotogoto_B;//跳转到直接取票
}
if(wait_sem(semid,INDEX_SIGNAL_SEAT))//如果没有空座,则等待空座
sem_p(semid,INDEX_SIGNAL_SEAT);
goto_B:
if(wait_sem(semid,INDEX_MUTEX))//等待操作信号量释放
sem_p(semid,INDEX_MUTEX);//锁定操作信号量
*ticket=get_sem_val(semid,INDEX_SIGNAL_CUSTOMER)+1;//分配票号(票号是根据当天的总顾客数排的)
wait_num=(signal_seat—get_sem_val(semid,INDEX_SIGNAL_SEAT))-1;//获取当前等待的人数
printf("号码:
B%03d,",*ticket);
if(wait_num==0||*flag==0)
{
printf(”当前没有顾客正在等待。
\t");//wait_num大于等于0或者flag大于0,表示当前无人等待
print_time();
}
else
{
printf("有%d位顾客正在等待。
\t”,wait_num);
print_time();
}
printf("顾客B%03d正在等待办理业务.\t",*ticket);
print_time();
if(sem_v(semid,INDEX_SIGNAL_CUSTOMER)!
=0)//记录目前办理过业务和等待办理业务的顾客总数
{
printf(”对不起,V操作失败!
”);
exit
(1);
return—1;
}
sem_v(semid,INDEX_MUTEX);//释放控制进程访问资源的信号量
break;
case’C’:
if(get_sem_val(semid,INDEX_SIGNAL_SEAT)==0)
{
if((wait_num=my_random()%10)<5)
return0;//返回0表示顾客选择离开
printf(”目前没有空座位,但该顾客选择了等待.\n\n”);
}
if(get_sem_val(semid,INDEX_SIGNAL_C)〉0)//检查,如果有空窗口,则直接取票,不用判断座位
{
*flag=0;//将标志为设为0,标示没有顾客在等待,不用排队
gotogoto_C;//跳转到直接取票
}
if(wait_sem(semid,INDEX_SIGNAL_SEAT))//如果没有空座,则等待空座
sem_p(semid,INDEX_SIGNAL_SEAT);
goto_C:
if(wait_sem(semid,INDEX_MUTEX))//等待操作信号量释放
sem_p(semid,INDEX_MUTEX);//锁定操作信号量
*ticket=get_sem_val(semid,INDEX_SIGNAL_CUSTOMER)+1;//分配票号(票号是根据当天的总顾客数排的)
wait_num=(signal_seat—get_sem_val(semid,INDEX_SIGNAL_SEAT))—1;//获取当前等待的人数
printf(”号码:
C%03d,",*ticket);
if(wait_num==0||*flag==0)
{
printf("当前没有顾客正在等待。
\t");//wait_num大于等于0或者flag大于0,表示当前无人等待
print_time();
}
else
{
printf(”有%d位顾客正在等待。
\t”,wait_num);
print_time();
}
printf("顾客C%03d正在等待办理业务。
\t”,*ticket);
print_time();
if(sem_v(semid,INDEX_SIGNAL_CUSTOMER)!
=0)//记录目前办理过业务和等待办理业务的顾客总数
{
printf(”对不起,V操作失败!
");
exit
(1);
return—1;
}
sem_v(semid,INDEX_MUTEX);//释放控制进程访问资源的信号量
break;
}
return1;
}
/*顾客接受服务函数*/
voidservice(intsemid,charidentifyLabel,int*ticket,int*flag)
{
intneed_time=0;//用于记录