您的位置:首页 > 运维架构 > Linux

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

2017-08-07 15:57 337 查看
共享内存进程间通信机制主要用于实现进程间大量的数据传输。

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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: