標籤:style 使用 io ar for 資料 sp amp linux
此程式實現沒有親緣關係的兩個進程間通過共用記憶體進行資料通訊。
同時,使用訊號量保證兩個進程的讀寫同步:發送方在寫共用記憶體時,接收方不能讀資料;接收方在讀資料時,發送方不能寫資料。
1、fork建立子進程
2、使用二元訊號量,同步讀寫端
fork_shm.c
#include<stdio.h>#include<sys/types.h>#include<unistd.h>#include"send_recv.h"int main(void){printf("fork test!\n");pid_t pid;if((pid=fork())==-1)printf("fork error");else if(pid==0){printf("in the child process\n");printf("the father process's ppid is %d\n",getppid());fork_recv();}else{//sleep(1);printf("in the parent process\n");printf("the son process's pid is %d\n",getpid());fork_send();}return 0;}
send_recv.c
#include"fork_recv.c"#include"fork_send.c"int fork_recv();int fork_send();
fork_send.c
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/shm.h>#include <sys/ipc.h>#include <sys/sem.h>#include <string.h>int fork_send(){int running=1;int shid;int semid;int value;void *sharem=NULL;struct sembuf sem_b;sem_b.sem_num = 0;sem_b.sem_flg = SEM_UNDO;if((semid=semget((key_t)123456,1,0666|IPC_CREAT))==-1){perror("semget");exit(EXIT_FAILURE);}if (semctl(semid, 0, SETVAL, 0) == -1){printf("sem init error"); if(semctl(semid,0,IPC_RMID,0)!=0){perror("semctl");exit(EXIT_FAILURE);}exit(EXIT_FAILURE);}shid=shmget((key_t)654321,(size_t)2048,0600|IPC_CREAT);if(shid==-1){perror("shmget");exit(EXIT_FAILURE);}sharem=shmat(shid,NULL,0);if(sharem==NULL){perror("shmat");exit(EXIT_FAILURE);}while(running){if((value=semctl( semid, 0, GETVAL ))==0){printf("write data operate\n");printf("please input something:\n");scanf("%s",sharem);sem_b.sem_op = 1;if (semop(semid, &sem_b, 1) == -1) {fprintf(stderr, "semaphore_p failed\n");exit(EXIT_FAILURE);}}if(strcmp(sharem,"end")==0)running--;}shmdt(sharem);return 0;}
fork_recv.c
#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <unistd.h>#include <string.h>#include <sys/ipc.h>#include <sys/shm.h>#include <sys/sem.h>int fork_recv(){int running=1;char *shm_p=NULL;int shmid;int semid;int value;struct sembuf sem_b;sem_b.sem_num = 0;sem_b.sem_flg = SEM_UNDO;if((semid=semget((key_t)123456,1,0666|IPC_CREAT))==-1){perror("semget");exit(EXIT_FAILURE);}shmid=shmget((key_t)654321,(size_t)2048,0600|IPC_CREAT);if(shmid==-1){perror("shmget");exit(EXIT_FAILURE);}shm_p=shmat(shmid,NULL,0);if(shm_p==NULL){perror("shmat");exit(EXIT_FAILURE);}while(running){if((value=semctl( semid, 0, GETVAL ))==1){printf("read data operate\n");sem_b.sem_op = -1;if (semop(semid, &sem_b, 1) == -1) {fprintf(stderr, "semaphore_p failed\n");exit(EXIT_FAILURE);}printf("%s\n",shm_p);}if(strcmp(shm_p,"end")==0)running--;}shmdt(shm_p);if(shmctl(shmid,IPC_RMID,0)!=0){perror("shmctl");exit(EXIT_FAILURE);}if(semctl(semid,0,IPC_RMID,0)!=0){perror("semctl");exit(EXIT_FAILURE);}return 0;}
linux下多進程+訊號量+共用記憶體編程