【Linux 进程间通信】管道和共享内存
创始人
2024-05-25 09:29:09
0

1.进程间通信的概念

2.匿名管道

匿名管道的5个特点

  1. 管道是一个单向通信的通信信道;

  1. 匿名管道作用与具有血缘关系的进程,常用于父子进程;

  1. 管道是一个文件,生命周期随进程;

  1. 管道自带同步机制、原子性;

  1. 管道是面向字节流;

管道的4种结果

  1. 读端快且写端慢或者不写,读端要等待写端;

  1. 写端快且读端慢或者不读,写端要等待读端;

  1. 读端关闭,写端收到SIGPIPE信号直接终止

  1. 写端关闭,读端读完pipe内部的数据,然后再读会返回0,表明已经读到文件结尾;

pipe函数

#include
#include
#include
#includeint main()
{int pipefd[2]={0};//创建匿名管道if(pipe(pipefd)!=0){perror("pipe error!\n");exit(1);}if(fork()==0)//创建子进程{close(pipefd[0]);//子进程关闭读const char* message="hello world\n";while(1){write(pipefd[1],message,strlen(message));sleep(1);}exit(1);}close(pipefd[1]);//父进程关闭写while(1){char* buffer[64];ssize_t s=read(pipefd[0],buffer,sizeof(buffer)-1);if(s==0){printf("子进程关闭写入\n");break;}else if(s>0){buffer[s]=0;printf("child say to father:%s",buffer);}else//s==0说明写端关闭,且读端把内容读完{printf("读取失败\n");break;    }}return 0;
}

执行结果

原理

3.命名管道

命名管道的情况和特点和匿名管道相同,但是命名可以运用到任意进程

mkfifo函数

server.c

#include
#include
#include
#include
#include
#include
#define MYFIFO "./myfifo"int main()
{umask(0);//把umask设置0if(mkfifo(MYFIFO,0666)<0){perror("mkfifo fail\n");exit(1);}int fd = open("myfifo",O_RDONLY);//服务器端以读方式打开文件if(fd<0){perror("open fail\n");exit(2);}while(1){char buffer[64];ssize_t s=read(fd,buffer,63);//read返回值读取的字节数if(s>0){buffer[s]=0;if(strcmp(buffer,"ls")==0)//输入ls就进程替换ls -l命令{execlp("ls","ls","-l",NULL);return(1);}elseprintf("client say to server:%s\n",buffer);}else if(s==0){printf("client close");break;}else{printf("read fail");break;}}return 0;
}

client.c

#include
#include
#include
#include
#include
#include
#define MYFIFO "./myfifo" int main()
{int fd=open(MYFIFO,O_WRONLY);//用户端以写的方式打开管道文件if(fd<0){perror("open\n");return 1;}while(1){char message[64];printf("please enter:");fflush(stdout);//刷新标准输出流ssize_t s=read(0,message,63);//从键盘读message[s]=0;write(fd,message,strlen(message)-1);//写到管道文件的缓冲区}return 0;
}

进程使用管道通信,不会把内容写到磁盘中去,会在缓冲区中读写;

4.共享内存

共享内存的效率是最高的因为它是使用直接虚拟地址映射来写入和读写数据的,不像管道需要使用read和write来读写

4.1共享内存的创建

shmget和ftok接口

#include
#include
#include
#include#define PATHNAME "./"
#define PROJID 0x5555
int main()
{key_t key=ftok(PATHNAME,PROJID);//获取一个唯一key值int shmid=shmget(key,4096,IPC_CREAT);//创建共享内存printf("key:%d,shmid:%d\n",key,shmid);return 0;
}

创建共享内存,程序执行完毕不会被OS回收

4.2删除共享内存

命令行:

代码:

    shmctl(shmid,IPC_RMID,NULL);//删除共享内存

4.3进程连接到共享内存(shmat),去关联(shmdt)

4.4简单使用共享内存通信

clien.c

#include
#include
#include
#include
#include
#define PATHNAME "./"
#define PROJID 0x5555int main()
{key_t key=ftok(PATHNAME,PROJID);int shmid=shmget(key,4096,IPC_CREAT|0666);char* mem=shmat(shmid,NULL,0);//关联printf("client process attaches success\n");while(1)//打印共享内存的内容{printf("%s\n",mem);sleep(1);}shmdt(mem);//去关联return 0;
}

server.c

#include
#include
#include
#include
#include
#define PATHNAME "./"
#define PROJID 0x5555
int main()
{key_t key=ftok(PATHNAME,PROJID);int shmid=shmget(key,4096,IPC_CREAT|0666);//创建一个共享内存并初始化权限为0666;if(shmid<0){perror("shmget\n");return 1;}char* mem=(char*)shmat(shmid,NULL,0);//关联printf("server process attaches success\n");char i='a';while(i<='z')//往共享内存写入数据{mem[i-'a']=i;i++;mem[i-'a']=0;sleep(2);}shmdt(mem);//去关联printf("server process detach success\n");shmctl(shmid,IPC_RMID,NULL);//关闭共享内存printf("shared memory close\n");return 0;
}

执行结果:

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...