Linux笔记(18)-管道操作与fifo文件

  1. 管道的读写行为
1. 读操作:
    a. 有数据可以读
        read(fd) -- 正常读取,返回读取的字节数
    b. 无数据可以读
        (1) 如果读写两端被关闭
            read会解除阻塞,返回0。相当是读文件读到了尾部
        (2) 如果没有全部关闭
            read将阻塞
2. 写操作:
    a. 读端被关闭:
        (1) 如果管道内被塞满,则管道破裂,进程会被终止
            内核将向进程发送SIGPIPE信号,然后终止进程
    b. 读端没有被关闭:
        (1) 如果缓冲区写满,则write阻塞,等待管道内容被读取后再写入
        (2) 如果没有被写满,则write正常写操作
  1. 查看pipe的缓存区大小
1. 终端命令
    ulimit -a
2. 函数
    a. 函数原型:
        long fpathconf(int fd, int name);
        long pathconf(const char* path,int name)
    b. 参数:
        fd:当使用函数fpathconf时,传入的是文件描述符
        path:当使用pathconf时,传入的是文件路径
        name:表示要查看的信息,可选有:
            _PC_LINK_MAX,_PC_MAX_CANON,_PC_MAX_INPUT,_PC_PATH_MAX,_PC_PIPE_BUF,_PC_CHOWN_RESTRICTED,_PC_NO_TRUNC,_PC_VDISABLE
3. 测试
    long size = fpathconf(fd[0], _PC_PIPE_BUF);
    printf("size = %ld\n", size);   //默认大小为4K,即4096byte
  1. 设置管道的非阻塞
1. 使用文件操作符修改操作函数fcntl:
    a. 先获取原来的信息
        int flags = fcntl(fd[0],F_GETFL);   //如果修改fd[0]则表示读端非阻塞
    b. 添加非阻塞O_NONBLOCK
        flags = flags | O_NOBLOCK
        fcntl(fd[0], F_SETFL, flags);
  1. fifo文件:first-in first-out special file
1. 特点:
    a. 它是文件系统的一部分
    b. 当使用ls -l查看该文件时,其类型为p,即管道。(称为:有名管道)
    c. 它是一个伪文件,在磁盘上的大小永远为0
    d. 当创建一个fifo文件时,会在内核中开辟一块与之对于缓冲区,用于存储数据
        当open一个fifo文件后,会获取一个fd,读写数据时,操作系统完成由fifo文件和内核缓冲区的数据交换
2. 使用场景
    适用于没有血缘关系的进程间通信
3. 创建方式:
    a. 终端命令
        mkfifo 
    b. 系统函数
        int mkfifo(const char *pathname, mode_t mode);  //函数创建时,需要提供创建时的权限
4. fifo文件操作
    a. open/close:文件开关操作
    b. read/write:文件读写操作
    不能进行lseek<重置文件指针>操作
5. 进程间通信 -- 类似于操作文件在进程间通信
    a. 创建fifo文件 -- myfifo
    b. 当前将会有两个进程A(源文件a.c),B(源文件b.c)
    c. 若进程A为读操作 -- a.c
        int fd_a = open("myfifo",O_RDONLY);
        char buf[256];
        read(fd_a,buf,sizeof(buf));
        close(fd_a);
    d. 若进程B为写操作 -- b.c
        int fd_b = open("myfifo",O_WRONLY);
        write(fd_b,"hello,world",11);
        close(fd_b);
6. fifo文件与普通文件在进程间通信的区别
    fifo文件为管道,所以读写操作会有阻塞性质。普通文件可能需要在操作读写时使用sleep函数保证不会出现读写交叉。

你可能感兴趣的:(Linux学习)