{
/* 设置信号量结构 */ sem->sem_num=semnum; sem->sem_op=semop; sem->sem_flg=semflg; }
int begin() {
char *addr, end; int shmid;
int semid_empty, semid_full1,semid_full2, semid_mutex; struct sembuf sem_tmp;
/*开辟共享存储区*/
if ((shmid = shmget(SHMKEY, BUFF_LEN * PRODUCT_LEN+3, 0777|IPC_CREAT|IPC_EXCL)) == -1) {
if (errno == EEXIST) {
printf(\
printf(\ scanf(\
if(end == 'y' || end == 'Y') {
/* 共享存储区、信号量并不随程序的结束而被删除,如果我们没删除的话, 可以用ipcs命令查看,用ipcrm删除 */
/*释放缓冲区*/
shmid = shmget(SHMKEY, BUFF_LEN * PRODUCT_LEN+3, 0777); if (shmctl(shmid,IPC_RMID,0) < 0) perror(\
/*同时释放信号量*/
semid_mutex = semget(SEMKEY_MUTEX,1, 0777);/*获取全局信号量id*/ semid_empty = semget(SEMKEY_EMPTY,1, 0777); semid_full1 = semget(SEMKEY_FULL1,1, 0777); semid_full2 = semget(SEMKEY_FULL2,1, 0777); semctl(semid_mutex,0,IPC_RMID); semctl(semid_empty,0,IPC_RMID); semctl(semid_full1,0,IPC_RMID); semctl(semid_full2,0,IPC_RMID); } } else
printf(\ return -1; }
addr = (char*)shmat(shmid, 0, 0);/*连接缓冲区*/
memset(addr, 0, BUFF_LEN * PRODUCT_LEN+3); //初始化存储区 为0 shmdt(addr); /*离开缓冲区*/
/*创建3个信号量:1个用于对缓冲区互斥,2个用于生产者、消费者同步*/ if((semid_mutex = semget(SEMKEY_MUTEX,1, 0777|IPC_CREAT|IPC_EXCL))==-1) {
if (errno == EEXIST)
printf(\ else
printf(\ return -1; }
if((semid_empty= semget(SEMKEY_EMPTY,1, 0777|IPC_CREAT|IPC_EXCL))==-1) {
if (errno == EEXIST)
printf(\ else
printf(\ return -1; }
if((semid_full1 = semget(SEMKEY_FULL1,1, 0777|IPC_CREAT|IPC_EXCL))==-1) {
if (errno == EEXIST)
printf(\ else
printf(\ return -1; }
if((semid_full2= semget(SEMKEY_FULL2,1, 0777|IPC_CREAT|IPC_EXCL))==-1) {
if (errno == EEXIST)
printf(\ else
printf(\ return -1; }
/*给信号量赋初值*/
set_sembuf_struct(&sem_tmp, 0, BUFF_LEN, 0);/*BUFF_LEN*/ semop(semid_empty, &sem_tmp,1);
set_sembuf_struct(&sem_tmp, 0, 0, 0);/*0*/ semop(semid_full1, &sem_tmp,1);
set_sembuf_struct(&sem_tmp, 0, 0, 0);/*0*/ semop(semid_full2, &sem_tmp,1);
set_sembuf_struct(&sem_tmp, 0, 1, 0);/*1*/ semop(semid_mutex, &sem_tmp,1);
return 0; }
/*下面的P,V是对系统调用的简单封装*/ int P(int semid) {
struct sembuf p_buf; p_buf.sem_num = 0; p_buf.sem_op = -1; p_buf.sem_flg = 0;
if(semop(semid, &p_buf, 1)==-1)/*semop参见课件ppt*/ {
perror (\ exit (1); } else
return 0; }
int V(int semid) {
struct sembuf v_buf;/*struct 参见课件ppt*/ v_buf.sem_num = 0; v_buf.sem_op = 1; v_buf.sem_flg = 0;
if(semop(semid, &v_buf, 1)==-1) { perror (\ exit (1); } else
return 0; }
int father()
{
int semid_empty, semid_full1,semid_full2, semid_mutex;/*信号量集合id*/ int rc1,rc2,rc3;
semid_mutex = semget(SEMKEY_MUTEX,1, 0777);/*获取全局信号量id*/ semid_empty = semget(SEMKEY_EMPTY,1, 0777); semid_full1 = semget(SEMKEY_FULL1,1, 0777); semid_full2 = semget(SEMKEY_FULL2,1, 0777);
rc1=semctl(semid_empty,0,GETVAL); rc2=semctl(semid_mutex,0,GETVAL); if(rc1==0) {
return 1; //不能放 則等待 }
if(rc2==0 ) {
return 1; }
P(semid_empty);/*对私有信号量作P操作*/ P(semid_mutex);
printf(\ printf(\ V(semid_mutex); V(semid_full1);
rc3=semctl(semid_full1,0,GETVAL);
printf(\ return 0; }
int mother()
{ int semid_empty, semid_full1,semid_full2, semid_mutex;/*信号量集合id*/ int rc1,rc2,rc3;
semid_mutex = semget(SEMKEY_MUTEX,1, 0777);/*获取全局信号量id*/ semid_empty = semget(SEMKEY_EMPTY,1, 0777); semid_full1 = semget(SEMKEY_FULL1,1, 0777); semid_full2 = semget(SEMKEY_FULL2,1, 0777); rc1=semctl(semid_empty,0,GETVAL); rc2=semctl(semid_mutex,0,GETVAL);
if(rc1==0) {
return 1; //不能放 則等待
}
else if(rc2==0) {
return 1; }
P(semid_empty);/*对私有信号量作P操作*/ P(semid_mutex);
printf(\ printf(\ V(semid_mutex); V(semid_full2);
rc3=semctl(semid_full2,0,GETVAL); printf(\ return 0; }
int son() {
int semid_empty, semid_full1,semid_full2, semid_mutex;/*信号量集合id*/ int rc1,rc2;
semid_mutex = semget(SEMKEY_MUTEX,1, 0777);/*获取全局信号量id*/ semid_empty = semget(SEMKEY_EMPTY,1, 0777); semid_full1 = semget(SEMKEY_FULL1,1, 0777); semid_full2 = semget(SEMKEY_FULL2,1, 0777); rc2=semctl(semid_full1,0,GETVAL); rc1=semctl(semid_full2,0,GETVAL); if(rc1==0) {
return 1; //不能放 則等待 }
P(semid_full2);/*对私有信号量作P操作*/ P(semid_mutex);
printf(\ printf(\ oranges to get \\n\ printf(\ V(semid_empty); V(semid_mutex); return 0; }
int daughter() {