linux 文件类型

实践:

1、

写入管道时保证为原子的最大字节数

11 #define PIPE_BUF 4096 /* # bytes in atomic write to a pipe */

 

 

1、普通文件( 数据文件 )

标识:- ,普通文件是用于存放数据、程序等信息的文件,一般都长期地存放在外存储器(磁盘)中。普通文件又分为文本文件和二进制文件。

2、目录文件

标识:d ,目录文件是文件系统中一个目录所包含的目录项所组成的文件。

(免费学习视频教程分享:linux视频教程)

3、设备文件

块设备:标识:b

字符设备:标识:c

设备文件是用于为操作系统与设备提供连接的一种文件。在Linux系统中将设备作为文件来处理,操作设备就像是操作普通文件一样。每一个设备对应一个设备文件,存放在 /dev 目录中。

4、链接文件

标识:l ,似于 windows 下的快捷方式,链接又可以分为软链接(符号链接)和硬链接。

5、管道文件

标识:p, 管道文件主要用于在进程间传递数据的一种特殊文件。

6、套接字文件

标识:s, 主要用于不同计算机间网络通信的一种特殊文件。

 


 处理管道 - IBM 文档 https://www.ibm.com/docs/zh/aix/7.3?topic=io-working-pipes

/usr/include/linux/limits.h

11 #define PIPE_BUF 4096 /* # bytes in atomic write to a pipe */

处理管道

上次更新时间: 2023-03-24

管道是创建以允许两个进程进行通信的未命名对象。

一个进程读管道文件,另一个进程写管道文件。 此唯一的文件类型也称为先进先出 (FIFO) 文件。 FIFO 的数据块在循环队列中操作,内部保持读写指针来保留数据的 FIFO 顺序。 在 limits.h 文件中定义的 PIPE_BUF 系统变量指定写入管道时保证为原子的最大字节数。

Shell 使用未命名管道进行命令的流水线处理。 大部分未命名管道由 shell 创建。 |(垂直)符号代表进程之间的管道。 在以下示例中, ls 命令的输出将打印到屏幕上:
ls | pr

管道被尽可能作为常规文件处理。 通常,当前偏移量信息被存储在系统文件表中。 然而,因为管道由进程共享,读/写指针必须针对文件,而不是进程。 文件表条目由 open 子例程创建,对于打开的进程唯一,不是对于文件唯一。 对管道具有访问权的进程通过公用的系统文件表条目共享访问。

使用管道子例程

pipe 子例程创建进程间通道并返回两个文件描述符。 文件描述符 0 打开用于读取。 文件描述符 1 打开用于写入。 读操作以 FIFO 基础访问数据。 这些文件描述符用于 read, write, 和 close 子例程。

在下列实例中,创建一个子进程并通过管道发送回其进程标识:
#include <sys/types.h>
main()
{
        int p[2];
        char buf[80];
        pid_t pid;

        if (pipe(p))
        {
                  perror("pipe failed");
                exit(1)'
        }
        if ((pid=fork()) == 0)
        {
                                       /* in child process */
                close(p[0]);           /*close unused read */
                                       *side of the pipe */
                sprintf(buf,"%d",getpid()); 
                                       /*construct data */
                                       /*to send */
                write(p[1],buf,strlen(buf)+1);
                        /*write it out, including
                        /*null byte */
                exit(0);
        }
                                        /*in parent process*/
        close(p[1]);                    /*close unused write side of pipe */
        read(p[0],buf,sizeof(buf));     /*read the pipe*/
        printf("Child process said: %s/n", buf);
                                       /*display the result */
        exit(0);
}

如果进程读取空白管道,进程等待直到数据到达。 如果写入到太满的管道 ( PIPE_BUF),进程等待直到有可用的空间。 如果管道的写入端被关闭,随后对管道的读操作返回文件结尾。

控制管道的其他子例程是 popen 和 pclose 子例程:
弹出
创建管道(使用 pipe 子例程),然后派生以创建调用程序的副本。 子进程决定是应该读还是写,关闭管道的另一侧,然后调用 shell (使用 execl 子例程) 来运行期望的进程。

父进程关闭不使用的管道结尾。 这些关闭对于使得文件结尾测试正确运行必不可少。 例如,如果意图读取管道的子进程不关闭管道的写入端,那么将永远不会看到管道上的文件结尾情况,因为潜在激活了一个写进程。

将管道描述符与进程标准输入关联的常规方法是:

close(p[1]);
close(0);
dup(p[0]);
close(p[0]);

Close 子例程断开文件描述符 0(标准输入)。 dup 子例程返回已打开的文件描述符的重复项。 按升序分配文件描述符并返回第一个可用的文件描述符。 Dup 子例程的效果是将管道(读取端)的文件描述符复制到文件描述符 0,从而标准输入成为管道的读取端。 最后,先前的读取端被关闭。 过程与子进程从父进程写入类似。

pclose
关闭调用程序和要执行的 shell 命令之间的管道。 使用 pclose 子例程关闭任何以 popen 子例程打开的流。

Pclose 子例程等待关联的进程结束,然后关闭并返回命令的退出状态。 此子例程比 close 子例程更好,因为在关闭管道之前 pclose 等待子进程结束。 同等重要的是,当进程创建多个子进程时,只能存在有限数目的未完成子进程,即使它们中的一些已经完成任务。 执行等待允许子进程完成它们的任务。

 

 

 

 

 

posted @ 2023-11-27 10:03  papering  阅读(28)  评论(0编辑  收藏  举报