进程间共享内存(信号量实现同步)

时间:2022-11-17 15:18:39
 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <unistd.h>
 4 #include <sys/types.h>
 5 #include <sys/shm.h>
 6 #include <sys/ipc.h>
 7 #include <sys/sem.h>
 8 #include <string.h>
 9 int main(int argc, char* argv[])
10 {
11   int running = 1;
12   int shid;
13   int semid;
14   int value;
15   int read_num;
16   FILE *stream;
17   char* sharem=NULL;
18   struct sembuf sem_b;
19   sem_b.sem_num = 0;
20   sem_b.sem_flg = SEM_UNDO;
21                                                            
22   if((semid = semget((key_t)123456,1,0666|IPC_CREAT))==-1)
23     {
24       perror("semget");
25       exit(EXIT_FAILURE);
26     }
27   if(semctl(semid,0,SETVAL,0)==-1)
28     {
29       printf("sem init error");
30       if(semctl(semid,0,IPC_RMID,0)!=0)
31     {
32       perror("semctl");
33       exit(EXIT_FAILURE);
34     }
35       exit(EXIT_FAILURE);
36     }
37   shid = shmget((key_t)654321,(size_t)30,0600|IPC_CREAT);
38   if(shid == -1)
39     {
40       perror("shmget");
41       exit(EXIT_FAILURE);
42     }
43   sharem = shmat(shid,NULL,0);
44   if(sharem==NULL)
45     {
46       perror("shmat");
47       exit(EXIT_FAILURE);
48     }
49    stream = fopen("data.in","r");
50   while(running)
51     {
52       // printf("write data operate\n");
53       // while((semctl(semid,0,GETVAL))==1);
54       if((value=semctl(semid,0,GETVAL))==0)
55     {
56                                                                
57     // if((read_num = fread(sharem,20,1,stream))==0)
58     //          running--;
59           if(fscanf(stream,"%s",sharem)!=EOF)
60         {
61                printf("%s\n",sharem);
62            sem_b.sem_op = 1;
63            if(semop(semid,&sem_b,1)==-1)
64              {
65                 printf("error\n");
66                 exit(EXIT_FAILURE);
67                  }
68         }
69           else   break;
70     }
71     }
72   printf("send completed\n");
73   fclose(stream);
74   shmdt(sharem);
75   return 0;
76 }

以上是sender进程。

 1 /*receiver.c*/
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <unistd.h>
 5 #include <sys/types.h>
 6 #include <sys/shm.h>
 7 #include <sys/ipc.h>
 8 #include <sys/sem.h>
 9 #include <string.h>
10 int main(int argc, char *argv[])
11 {
12   int running = 1;
13   char *shm_p = NULL;
14   int shmid;
15   int value;
16   int semid;
17   FILE *stream;
18                                                     
19   struct sembuf sem_b;
20   sem_b.sem_num=0;
21   sem_b.sem_flg=SEM_UNDO;
22                                                     
23   semid=semget((key_t)123456,1,0666|IPC_CREAT);
24   shmid = shmget((key_t)654321,(size_t)30,0600|IPC_CREAT);
25   shm_p = shmat(shmid,NULL,0);
26   printf("read data operate\n");
27   //stream = fopen("data.out","w+");
28   char buffer[50];
29   while(running)
30     {
31       while((value=semctl(semid,0,GETVAL))==1)
32     {
33       stream = fopen("data.out","a+");
34       sem_b.sem_op = -1;
35       if(semop(semid,&sem_b,1)==-1)
36         {
37           printf("error\n");
38           exit(EXIT_FAILURE);
39         }
40       strcpy(buffer,shm_p);
41       printf("%s\n",buffer);
42       //fwrite(shm_p,20,1,stream);
43       fprintf(stream,"%s\n",buffer);
44       fclose(stream);
45     }
46       if(strcmp(shm_p,"end")==0)
47     running--;
48     }
49   shmdt(shm_p);
50   if(shmctl(shmid,IPC_RMID,0)!=0)
51     {
52       perror("shmctl");
53       exit(EXIT_FAILURE);
54     }
55   if(semctl(semid,0,IPC_RMID,0)!=0)
56     {
57       perror("semctl");
58       exit(EXIT_FAILURE);
59     }
60   return 0;
61 }

以上是receiver进程。

sender:从data.in中读取数据写入到共享内存。

receiver:从共享内存读数据,写入到data.out。

以end作为结束符。

用信号量作为同步机制。