共享内存:
1. 共享内存是一种最为有效的进程间通信方式,进程可以直接读写内存,更不需要任何数据的拷贝
2.为了多个进程之间交互信息,内核专门留出一块内存区,可由需要访问的进程将其映射到自己的私有地址空间
3.进程可以直接读取这一段内存区,而不需要数据的拷贝,从而大大的提高了效率
4.由于多个进程共享一段内存,因此需要某种同步机制,如互斥和信号量等
练习:实现用共享内存实现两程序间通信,即程序在终端将数据写入内存中,另一程序将该段内存数据读出,并输出
注意:进程间同步是该程序的关键
调试:
1 ./write /
2 /read /
注意:本程序运行时,需要先运行写端,这也是本程序的缺陷之处
运行效果:
写端输入:
读端输出:
write.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#define MMSIZE 1024
#include <sys/shm.h>
#include <unistd.h>
#include <signal.h>
void handler(int signum)
{
return;
}
int main(int argc, const char *argv[])
{
key_t key;
int sh_id;
pid_t pid;
char *addr = NULL;
signal(SIGUSR1,handler);
if((key = ftok(argv[1],'k') ) < 0)
{
perror("FAIL TO GET THE KEY:");
exit(EXIT_FAILURE);
}
if( (sh_id = shmget(key,MMSIZE,IPC_CREAT | 0666)) < 0 )
{
perror("FAIL TO CREAT THE SHARE MEMORY");
exit(EXIT_FAILURE);
}
printf("write sh_id is %d\n",sh_id);
if((addr = (char *)shmat(sh_id,NULL,0)) == (char *)-1)
{
perror("FAIL TO SNATCH SHARE MEMORY");
exit(EXIT_FAILURE);
}
printf("the write id is %d\n",getpid());
*((int *)addr)= getpid();
pause();
pid = *((int *)addr);
printf("the read id is %d\n",pid);
while(1)
{
fgets(addr,MMSIZE,stdin);
addr[strlen(addr) - 1] = '\0';
kill(pid,SIGUSR1);
pause;
if(strncmp(addr,"quit",4) == 0)
{
if(shmdt(addr) < 0)
{
perror("FAIL TO EXTRACTE SHAE MEMORY");
exit(EXIT_FAILURE);
}
if(shmctl(sh_id,IPC_RMID,NULL) < 0)
{
perror("FAIL TO SHMTL:");
exit(EXIT_FAILURE);
}
goto next;
}
}
next:
kill(pid,SIGUSR1);
exit(EXIT_FAILURE);
return 0;
}
read.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<signal.h>
#include <sys/types.h>
#include <sys/ipc.h>
#define MMSIZE 1024
#include <sys/shm.h>
#include <unistd.h>
void handler(int signum)
{
return;
}
int main(int argc, const char *argv[])
{
key_t key;
int sh_id;
pid_t pid;
char *addr = NULL;
signal(SIGUSR1,handler);
if((key = ftok(argv[1],'k') ) < 0)
{
perror("FAIL TO GET THE KEY:");
exit(EXIT_FAILURE);
}
if( (sh_id = shmget(key,MMSIZE,IPC_CREAT | 0666)) < 0 )
{
perror("FAIL TO CREAT THE SHARE MEMORY");
exit(EXIT_FAILURE);
}
printf("read sh_id is %d\n",sh_id);
if((addr = (char *)shmat(sh_id,NULL,0)) == (char *)-1)
{
perror("FAIL TO SNATCH SHARE MEMORY");
exit(EXIT_FAILURE);
}
printf("the read id is %d\n",getpid());
pid = *((int *)addr);
printf("the write id is %d\n",pid);
*((int *)addr) = getpid();
kill(pid,SIGUSR1);
while(1)
{
pause();
printf("%s\n",addr);
kill(pid,SIGUSR1);
if(strncmp(addr,"quit",4) == 0)
{
if(shmdt(addr) < 0)
{
perror("FAIL TO EXTRACTE SHAE MEMORY");
exit(EXIT_FAILURE);
}
goto next;
}
}
next:
kill(pid,SIGUSR1);
exit(EXIT_FAILURE);
return 0;
}