二、传统的进程间通信-管道文件
管道是UNIX系统中最古老的进程间通信技术,古老意味着所有系统都支持,早期的管道是半双工通信,现有的系统管道是全双工通信
管道就是一种特殊的文件,数据在文件中是流动的,读取之后就自动消失,如果文件中没有数据则会阻塞
有名管道:基于有文件名的管道文件的通信
编程模型
进程A 进程B
创建管道
打开管道 打开管道
写数据 读数据
关闭管道 关闭管道
删除管道
创建有名管道文件:
1、命令 mkfifo
2、函数
int mkfifo(const char *pathname,mode_t mode);
功能:创建有名管道
pathname:管道文件路径
mode:管道文件权限 0664
测试结果如下:
1. **使用 fgets
读取输入**:这样可以安全地读取一行输入,避免了缓冲区溢出的问题。 2. **去掉末尾的换行符**: buf[strcspn(buf, "\n")] = '\0';
这行代码将输入中的换行符替换为字符串结束符,以便后续处理。
2.scanf
函数在默认情况下使用空格、换行符和制表符作为分隔符,因此它不会读取包含空格的字符串。具体来说,当你使用 %s
格式说明符时, scanf
只会读取到第一个空格为止,之后的内容会被忽略。例如:
1. 匿名管道:
只适合通过fork创建父子进程之间使用
int pipe(int pipefd[2]);
功能:创建一个匿名管道文件
通过pipefd返回该匿名管道文件的读权限fd和写权限的fd
pipefd[0] 用于读匿名管道
pipefd[1] 用于写匿名管道
编程模型:
父进程 子进程
获取一对fd
创建子进程 拷贝\共享一对fd
关闭读 关闭写
写数据 读数据
关闭写 关闭读
#include <stdio.h>
#include<sys/ipc.h>
#include<sys/types.h>
int main(int argc,const char* argv[])
{
//创建内存空间
int shmid=shmget(ftok(".",110),4096,IPC_CREAT|0664);
if(shmid<0)
{
perror("shmget");
return -1;
}
//映射共享内
char* shm=shmdt(shmid,NULL,0);
if(shm==(void *)-1)
{
perror("shmat");
shmctl(shmid,IPC_STAT,NULL);
return -1;
}
pid_t pid=0;
printf("");
scanf("%u",&pid);
//写数据并通知其他进程
for()
{
printf(">>>");
//向shm(内存)中写入
scanf("%s",shm);
kill(pid,);
if(0==strcmp("quit",chm))
{
printf("通信结束\n");
break;
}
}
return 0;
}
测试结果: