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;
}
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;
}
相关文章推荐
- Linux系统编程——进程间通信:共享内存
- linux高级编程基础系列:System V进程间通信(信号量、共享内存)
- Linux的进程编程-之二-进程间通信(共享内存)
- 【Linux系统编程】进程间通信--共享内存
- Linux进程间通信(IPC)编程实践(六)共享内存的使用-mmap
- Linux进程间通信(IPC)编程实践(八)共享内存的使用-POSIX 共享内存(API)
- Linux下网络编程(3)——进程间通信(IPC),共享内存,传递结构体数据
- Linux进程间通信(IPC)编程实践(七)共享内存的使用-System V共享内存(API)
- Linux环境进程间通信(五)——共享内存
- Linux进程间通信——使用共享内存
- Linux进程间通信之共享内存
- Linux环境进程间通信(五): 共享内存(上)
- 【转】Linux进程间通信—— 共享内存(下)
- Linux环境进程间通信(五): 共享内存(上)
- LINUX_C编程实战-《进程间的通信》-共享内存
- Linux进程间通信-------共享内存之mmap详解
- Linux环境进程间通信(五): 共享内存(上)
- Linux进程间通信--mmap共享内存(一)
- Linux下的C语言编程——共享内存及有名管道的使用
- Linux进程间通信——使用共享内存