• 进程间通信


    一个管道文件的通信半双工的,且不能用lseek()函数操作,其他操作与普通文件一样。

    匿名pipe

    #include <unistd.h>
    int pipe(int pipefd[2]);
    
    • 功能:创建无名管道。
    • 参数:
      pipefd : 为 int 型数组的首地址,其存放了管道的文件描述符 pipefd[0]pipefd[1]。当一个管道建立时,它会创建两个文件描述符 fd[0]fd[1]。其中 fd[0] 固定用于读管道,而 fd[1] 固定用于写管道。一般文件 I/O的函数都可以用来操作管道(lseek() 除外)。
    • 返回值:
      成功:0
      失败:-1

    命名pipe

    #include <sys/types.h>
    #include <sys/stat.h>
    int mkfifo(const char *pathname, mode_t mode);
    
    • 功能:
      命名管道的创建。
    • 参数:
      pathname : 普通的路径名,也就是创建后 FIFO 的名字。
      mode : 文件的权限,与打开普通文件的 open() 函数中的 mode 参数相同。(0644)
    • 返回值:
      成功:0 状态码
      失败:如果文件已经存在,则会出错且返回 -1。
    • 注意:
      管道默认大小65536字节

    管道读写四种情况

    1. 写端文件描述符全部关闭 (管道写端引用计数为0) ,管道没数据,read会返回0,就像读到文件末尾一样,不设置errno
    2. 写端没关闭,管道没数据,则read阻塞。若读端设置非阻塞,read返回-1,errno设置为EAGAIN
    3. 读端都关闭,写端进程会收到信号SIGPIPE,进程异常终止。
    4. 读端没关闭,管道写满,写端阻塞。若写端设置非阻塞,write返回-1,errno设置为EAGAIN

    内存映射:mmap()函数

    #include <sys/mman.h>
    void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
    
    • 功能:
      一个文件或者其它对象映射进内存
    • 参数:
      addr : 文件映射到内存哪个位置, 通常设为NULL, 由系统指定
      length:映射到内存的文件长度
      prot: 映射区的保护方式, 最常用的 :
      a) 读:PROT_READ
      b) 写:PROT_WRITE
      c) 读写:PROT_READ | PROT_WRITE
      flags: 映射区的特性, 可以是
      a) MAP_SHARED(直写法): 写入映射区的数据会复制回文件, 且允许其他映射该文件的进程共享。
      b) MAP_PRIVATE : 对映射区的写入操作会产生一个映射区的复制(copy - on - write), 对此区域所做的修改不会写回原文件
      fd:由open返回的文件描述符, 代表要映射的文件。
      offset:以文件开始处的偏移量, 必须是4k(内存页面大小)的整数倍, 通常为0, 表示从文件头开始映射
    • 返回值:
      成功:返回创建的映射区首地址
      失败:MAP_FAILED宏
    #include <sys/mman.h>
    int munmap(void *addr, size_t length);
    
    • 功能:
      释放内存映射区
    • 参数:
      addr:使用mmap函数创建的映射区的首地址
      length:映射区的大小
    • 返回值:
      成功:0
      失败:-1

    注意事项

    1. 创建映射区的过程中,隐含着一次对映射文件的读操作。
    2. 当MAP_SHARED时,要求:映射区的权限应 <=文件打开的权限(出于对映射区的保护)。而MAP_PRIVATE则无所谓,因为mmap中的权限是对内存的限制。
    3. 映射区的释放与文件关闭无关。只要映射建立成功,文件可以立即关闭。
    4. 特别注意,当映射文件大小为0时,不能创建映射区。所以,用于映射的文件必须要有实际大小。mmap使用时常常会出现总线错误,通常是由于共享文件存储空间大小引起的。
    5. munmap传入的地址一定是mmap的返回地址。坚决杜绝指针++操作。
    6. mmap创建映射区出错概率非常高,一定要检查返回值,确保映射区建立成功再进行后续操作。
  • 相关阅读:
    异常作业
    多态作业
    封装和继承作业
    类和对象作业
    多重循环、方法作业
    选择语句+循环语句作业
    数据类型和运算符作业
    初识Java作业
    C 数据结构堆
    C基础 旋转数组查找题目
  • 原文地址:https://www.cnblogs.com/rookiezjz/p/15817711.html
Copyright © 2020-2023  润新知