linux编程---进程间通信---共享内存

xiaoxiao2021-02-28  77

共享内存进程间通信机制主要用于实现进程间大量的数据传输。

1  创建共享内存

  #include <sys/ipc.h>   #include <sys/shm.h>

  int shmget(key_t key, size_t size, int shmflg);

2  共享内存控制

 int shmctl(int shmid, int cmd, struct shmid_ds *buf);

3  映射共享内存对象

void *shmat(int shmid, const void *shmaddr, int shmflg);

4分离共享内存对象

int shmdt(const void *shmaddr);

实例一

父子进程通过共享内存通信

#include<errno.h> #include<fcntl.h> #include<stdio.h> #include<string.h> #include<unistd.h> #include<sys/shm.h> #include<sys/wait.h> #include<stdlib.h> int main(int argc,char* argv[]) {     int childpid;     int id;     int i;     int buf[10];     char* ptr;     int totalbytes = 0;     key_t key;     key = ftok("tmp",3);         if((childpid = fork()) == -1)     {         perror("fork");         exit(EXIT_FAILURE);     }         if(childpid == 0)     {         //notice permission         if((id = shmget(key,20*sizeof(char),0666|IPC_CREAT)) == -1)         {             perror("failed to create shared memory segment");             exit(EXIT_FAILURE);         }         if((ptr = (char*)shmat(id,0,0)) == NULL)         {             if(shmctl(id,IPC_RMID,NULL) == -1)                 perror("failed to remove memory segment");                 exit(EXIT_FAILURE);         }         for(i=0;argv[1][i]!='\0';i++)         {             *ptr = argv[1][i];             ptr++;         }         printf("this is child.\nwrite argv[1] to shm.\nyou input charater count is %d\n",i);         exit(EXIT_SUCCESS);     }          else     {         wait(NULL);         if((id = shmget(key,10*sizeof(char),0666|IPC_CREAT)) == -1)         {             perror("shmget");             exit(EXIT_FAILURE);         }         if((ptr = (char*)shmat(id,0,0)) == NULL)         {             perror("shmat");             if(shmctl(id,IPC_RMID,NULL) == -1)                 perror("failed to remove memory segment");                 exit(EXIT_FAILURE);         }         printf("this is parent.\ninput character is %s\n",ptr);         if(shmctl(id,IPC_RMID,NULL) == -1)         {                 perror("failed to remove memory segment");                 exit(EXIT_FAILURE);         }         exit(EXIT_SUCCESS);     } }

实例二

两个进程通过共享内存通信

同时,使用信号量来保证两个进程的读写同步。

发送方程序如下

#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 main(int argc,char* argv[]) {         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;         key_t key;         key = ftok("tmp",3);         if((semid = semget(key,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);         }         key_t key1;         key1 = ftok("tmp2",4);         shid = shmget(key1,10*sizeof(char),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 charater:");                         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; }

接收方程序如下

#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 main(int argc,char* argv[]) {         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;         key_t key;         key = ftok("tmp",3);         if((semid = semget(key,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);         }         key_t key1;         key1 = ftok("tmp2",4);         shid = shmget(key1,10*sizeof(char),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)) == 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",sharem);                 }                 if(strcmp(sharem,"end") == 0)                         running--;         }         shmdt(sharem);         if(shmctl(shid,IPC_RMID,0) != 0)         {                         perror("shctl");                         exit(EXIT_FAILURE);         }         if(semctl(semid,IPC_RMID,0) != 0)         {                         perror("semctl");                         exit(EXIT_FAILURE);         }         return 0; }

转载请注明原文地址: https://www.6miu.com/read-81163.html

最新回复(0)