- #include <stdio.h>
- #include <unistd.h>
- #include <sys/shm.h>
- #include <sys/stat.h>
- #include <sys/sem.h>
- #ifndef _SEMUN_H
- #define _SEMUN_H
- union semun{
- int val;
- struct semid_ds *buf;
- unsigned short int *array;
- struct seminfo *_buf;
- };
- #endif
- int sem_id;
- int set_semvalue(void) //初始化信号量
- {
- union semun semunion;
- semunion.val = 1;
- if(semctl(sem_id,0,SETVAL,semunion) == -1) return 0;
- return 1;
- }
- void del_semvalue(void) //删除信号量
- {
- union semun semunion;
- if(semctl(sem_id,0,IPC_RMID,semunion) == -1)
- printf("failed to free semvalue\\n");
- }
- int semaphore_p(void) //p操作
- {
- struct sembuf sem_b;
- sem_b.sem_num = 0;
- sem_b.sem_op = -1;
- sem_b.sem_flg = SEM_UNDO;
- if(semop(sem_id,&sem_b,1) == -1)
- {
- printf("semaphore_p failed!\\n");
- return 0;
- }
- return 1;
- }
- int semaphore_v(void) //v操作
- {
- struct sembuf sem_b;
- sem_b.sem_num = 0;
- sem_b.sem_op = 1;
- sem_b.sem_flg = SEM_UNDO;
- if(semop(sem_id,&sem_b,1) == -1)
- {
- printf("semaphore_v failed!\\n");
- return 0;
- }
- return 1;
- }
- struct wr_mark{ //作为进程是否读取数据的标志
- char b_read;
- char c_read;
- char d_read;
- };
- int main(int argc,char* argv[])
- {
- pid_t pid_B,pid_C,pid_D; //进程号
- int seg_id,mark_id; //两个共享内存的ID
- char *share_memory;
- struct wr_mark *p_wr_mark; //两个共享内存的地址
- int mark_size = sizeof(struct wr_mark);
- int seg_size = 64;
- seg_id = shmget(IPC_PRIVATE,seg_size,IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR);
- mark_id = shmget(IPC_PRIVATE,mark_size,IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR); //获取两个共享内存的id
- share_memory = (char*)shmat(seg_id,0,0);
- p_wr_mark = (struct wr_mark*)shmat(mark_id,0,0); //映射
- p_wr_mark->d_read = 1;
- p_wr_mark->b_read = 1;
- p_wr_mark->c_read = 1; //设置初始状态使进程A最先运行,写入数据
- sem_id = semget((key_t)1234,1,0666|IPC_CREAT);
- if(!set_semvalue()) exit(0); //初始化信号量
- pid_B = fork();
- if(pid_B == 0) //进程B
- {
- pid_C = fork();
- if(pid_C == 0) //进程C
- {
- pid_D = fork();
- if(pid_D == 0) //进程D
- {
- //printf("process D is running\\n");
- int i;
- for(i=0 ; i<10 ; i++)
- {
- if(!semaphore_p()) exit(0); //p操作
- if(p_wr_mark->d_read == 0)
- {
- printf("process D recv %s\\n",share_memory);
- p_wr_mark->d_read = 1;
- }
- if(!semaphore_v()) exit(0); //v操作
- sleep(2);
- }
- }
- else //进程C
- {
- //printf("process C is running\\n");
- int i;
- for(i=0 ; i<10 ; i++)
- {
- if(!semaphore_p()) exit(0);
- if(p_wr_mark->c_read == 0)
- {
- printf("process C recv %s\\n",share_memory);
- p_wr_mark->c_read = 1;
- }
- if(!semaphore_v()) exit(0);
- sleep(2);
- }
- waitpid();
- }
- }
- else //进程B
- {
- //printf("process B is running\\n");
- int i;
- for(i=0 ; i<10 ; i++)
- {
- if(!semaphore_p()) exit(0);
- if(p_wr_mark->b_read == 0)
- {
- printf("process B recv %s\\n",share_memory);
- p_wr_mark->b_read = 1;
- }
- if(!semaphore_v()) exit(0);
- sleep(2);
- }
- waitpid();
- }
- }
- else //进程A
- {
- //printf("process A is running\\n");
- int i;
- for(i=0 ; i<10 ; i++)
- {
- if(!semaphore_p()) exit(0);
- if(p_wr_mark->d_read==1 && p_wr_mark->b_read==1 &&
- p_wr_mark->c_read==1)
- {
- sprintf(share_memory,"hello world%d",i);
- printf("process A have write data!\\n");
- p_wr_mark->b_read = 0;
- p_wr_mark->c_read = 0;
- p_wr_mark->d_read = 0;
- }
- if(!semaphore_v()) exit(0);
- sleep(2);
- }
- del_semvalue();
- waitpid();
- }
- shmdt(share_memory);
- shmdt(p_wr_mark);
- shmctl(seg_id,IPC_RMID,0);
- shmctl(mark_id,IPC_RMID,0);
- }
- //该片段来自于http://www.codesnippet.cn/detail/210120148603.html
来源: http://www.codesnippet.cn/detail/210120148603.html