您的位置:首页 > 房产 > 建筑 > 郑州制作网站的基本流程_江西省赣州市天气预报_关键词推广是什么_免费的关键词挖掘工具

郑州制作网站的基本流程_江西省赣州市天气预报_关键词推广是什么_免费的关键词挖掘工具

2025/4/11 20:30:34 来源:https://blog.csdn.net/huanghongqi11/article/details/146804965  浏览:    关键词:郑州制作网站的基本流程_江西省赣州市天气预报_关键词推广是什么_免费的关键词挖掘工具
郑州制作网站的基本流程_江西省赣州市天气预报_关键词推广是什么_免费的关键词挖掘工具

1 有名管道介绍

有名管道(Named Pipe),也称为 FIFO(First In First Out),是 Linux 进程间通信(IPC)的一种方式。FIFO 不同于管道之处在于它提供一个路径名与之关联,以 FIFO 的文件形式存在于文件系统中。这样,即使与 FIFO 的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过 FIFO 相互通信(能够访问该路径的进程以及 FIFO 的创建进程之间),因此,通过 FIFO 不相关的进程也能交换数据。

它与匿名管道的核心区别在于:

  1. 匿名管道 仅适用于 有亲缘关系的进程(如父子进程),而 有名管道 允许 任意进程(即使无亲缘关系)通过文件系统路径进行通信。

  2. 有名管道 在文件系统中有一个 持久化的节点(类似于文件),而匿名管道是临时的,仅存在于内存中。

2 shell 编程应用

  1. 打开一个 终端A 发送信息
# 创建命名管道
mkfifo mypipe
# 进程 A 写入数据
echo "Hello from Process A" > mypipe
  1. 打开一个终端B 接收信息
# 进程 B 读取数据
cat mypipe
  1. 在终端A或者终端B中要删除有名管道,需要手动删除
rm mypipe

3 进程中有名管道用到函数

3.1 mkfifo 函数

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int mkfifo(const char * pathname, mode_t mode)
  1. 其中输入形参:
    pathname:FIFO 文件的路径(如 “/tmp/myfifo”)。
    mode:权限模式(如 0666,表示所有用户可读写), mkfifo()建立的 FIFO 文件其他进程都可以用读写一般文件的方式存取。

具体案例如下:

mkfifo("/tmp/myfifo", S_IFIFO | 0666);  // S_IFIFO 可省略,因 mkfifo 已隐含
  1. 返回值:
    成功返回 0,失败返回 -1 并设置 errno。
  2. mkfifo()会依参数 pathname 建立特殊的 FIFO 文件,该文件必须不存在。

3.2 删除函数

  1. 可以利用停止信号,来触发删除函数,否则需要手动删除
unlink(const char * pathname);  // 删除 FIFO 文件
  1. 有可能存在残留的情况,最好程序启动的时候,删除残留。
if (access("/tmp/myfifo", F_OK) == 0) {unlink("/tmp/myfifo");
}

3.3 其它文件操作函数说明

  1. 只读方式打开,默认阻塞模式
int fd = open("/tmp/myfifo", O_RDONLY ); // 阻塞模式打开
  1. 只读方式打开,采用非阻塞方式
int fd = open("/tmp/myfifo", O_RDONLY | O_NONBLOCK); // 非阻塞模式打开
  1. 以只写方式打开,默认采用阻塞模式
int fd = open("/tmp/myfifo", O_WRONLY ); // 阻塞模式打开

如果没有写入端,open() 会 立即返回 -1,并设置 errno = ENXIO。

3.4 阻塞与非阻塞模式说明

在这里插入图片描述

3.5 注意事项

  1. 需要轮询(polling)的 IPC 通信。

  2. 避免死锁(如双向通信时双方都在等待对方)。

  3. 如果需要双工通讯,需要创建两个管道。

3.6 总结

在这里插入图片描述

4 代码演示

4.1 单工通讯

4.1.1 发送端

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>#define FIFO_PATH "/tmp/myfifo"int main() {// 创建 FIFO(如果不存在)if (mkfifo(FIFO_PATH, 0666) == -1) {perror("mkfifo failed");// 如果已存在,继续使用(不报错)}// 打开 FIFO(阻塞模式,等待读取端连接)int fd = open(FIFO_PATH, O_WRONLY);if (fd == -1) {perror("open failed");exit(EXIT_FAILURE);}// 写入数据char *msg = "Hello from writer!";if (write(fd, msg, strlen(msg) + 1) == -1) {perror("write failed");} else {printf("Writer sent: %s\n", msg);}close(fd);return 0;
}

4.1.2 接收端

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>#define FIFO_PATH "/tmp/myfifo"int main() {// 创建 FIFO(如果不存在)if (mkfifo(FIFO_PATH, 0666) == -1) {perror("mkfifo failed");// 如果已存在,继续使用(不报错)}// 打开 FIFO(阻塞模式,等待写入端连接)int fd = open(FIFO_PATH, O_RDONLY);if (fd == -1) {perror("open failed");exit(EXIT_FAILURE);}// 读取数据char buf[100];ssize_t bytes_read = read(fd, buf, sizeof(buf));if (bytes_read == -1) {perror("read failed");} else {printf("Reader received: %s\n", buf);}close(fd);// 程序退出后删除 FIFO(可选)unlink(FIFO_PATH);return 0;
}

4.2 双工通讯

下面用server 发送,client 接收实现全双工通讯。

4.2.1 服务器代码

server.c

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#define FIFO_READ "readfifo"
#define FIFO_WRITE "writefifo"
#define BUF_SIZE 1024
int main(void)
{int wfd,rfd;char buf[BUF_SIZE];int len;umask(0);if(mkfifo(FIFO_WRITE,S_IFIFO|0666)){printf("can't create FIFO %s beause %s",FIFO_WRITE,strerror(errno));exit(1);}umask(0);
wfd = open(FIFO_WRITE,O_WRONLY);
if(wfd == -1){
printf("open FIFO %s error :%s",FIFO_WRITE,strerror(errno));
exit(1);
}
while((rfd = open(FIFO_READ,O_RDONLY)) == -1){
sleep(1);
}
while(1) {
printf("Server:");
fgets(buf,BUF_SIZE,stdin);
buf[strlen(buf)-1] = '\0';
if(strncmp(buf,"quit",4) == 0) {
close(wfd);
unlink(FIFO_WRITE);
close(rfd);
exit(0);
}
write(wfd,buf,strlen(buf));
len = read(rfd,buf,BUF_SIZE);
if(len > 0) {
buf[len] = '\0';
printf("Client:%s\n",buf);
}
}
}

4.2.2 用户程序

linux中的 umask 函数主要用于:
在创建新文件或目录时,屏蔽掉新文件或目录不应有的访问允许权限。文件的访问允许权限共有9种,分别是:r w x r w x r w x(它们分别代表:用户读 用户写 用户执行 组读 组写 组执行 其它读 其它写 其它执行)。
其实这个函数的作用,就是设置允许当前进程创建文件或者目录最大可操作的权限,比如这里设置为0,它的意思就是0取反再创建文件时权限相与,也就是:(~0) & mode 等于八进制的值0666 & mode了,这样就是给后面的代码调用函数mkfifo给出最大的权限,避免了创建目录或文件的权限不确定性。**

**S_IFIFO|0666”指明创建一个命名管道且存取权限为0666,即创建者、与创建者同组的用户、其他用户对该命名管道的访问权限都是可读可写(这里要注意umask对生成的管道文件权限的影响)。

client.c

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#define FIFO_READ "writefifo"
#define FIFO_WRITE "readfifo"
#define BUF_SIZE 1024
int main(void)
{int wfd,rfd;char buf[BUF_SIZE];int len;umask(0);if(mkfifo(FIFO_WRITE,S_IFIFO|0666)){printf("can't create FIFO %s beause %s",FIFO_WRITE,strerror(errno));exit(1);}while((rfd = open(FIFO_READ,O_RDONLY)) == -1) {sleep(1);}Wfd = open(FIFO_WRITE,O_WRONLY);if(wfd == -1){printf("open FIFO %s error :%s",FIFO_WRITE,strerror(errno));exit(1);}while(1){len = read(rfd,buf,BUF_SIZE);if(len > 0) {buf[len] = '\0';printf("Server:%s\n",buf);}printf("Client:");fgets(buf,BUF_SIZE,stdin);buf[strlen(buf)-1] = '\0';if(strncmp(buf,"quit",4) == 0) {close(wfd);unlink(FIFO_WRITE);close(rfd);exit(0);}write(wfd,buf,strlen(buf));}return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com