-->

管道通信

了解完进程的特点,以及进程的创建方式。接下来就可以了解进程之间也是可以通信的。
在linux系统中,一共有7中文件类型,其中的管道文件就是用于进程间的通信的(pipe)
进程间的通信(Inter Process Conmunication),简称IPC,一般是进程间的通信,常用的有一下几种方式比如管道通信、信号通信、共享内存、消息队列、信号量组、POSIX信号量等。

  • 管道通信
    管道通信可以分为两种,其中有一种是匿名管道文件,另外一种是有名管道文件或者叫命名管道文件。

    • 匿名管道(pipe)文件由于没有名字,不能open,所以只能使用在父进程创建子进程中使用,也就是父进程和子进程通信
    • 命名管道文件是实体的文件(FIFO),可以open,所有可以使用在不同的进程间的通信。
  • 匿名管道(pipe)文件的使用

只能使用在父进程和父进程创建的子进程中

linux提供一个函数叫做pipe(int pipefd[2]),可以创建一个管道文件,有一个参数是两个整形元素数组,第一个元素pipefd[0]是读取端的文件描述符,第二个元素pipefd[2]是写入端的文件描述符,返回值成功返回0,失败返回-1

int main()
{
    int pipefd[2];

    // 创建管道文件
    pipe(pipefd);

    // 缓冲区
    char buffer[20] = {'\0'};

    // 接收子进程的状态
    int state;

    // 创建子进程
    int child_pid = fork();

    if (child_pid > 0)
    {
        // 父进程执行语句,写入数据
        strcpy(buffer, "hello");
        write(pipefd[1], buffer, sizeof(buffer));
        // 等待子进程结束
        wait(&state);
    }
    else if (child_pid == 0)
    {
        // 子进程执行语句,读取数据
        read(pipefd[1], buffer, sizeof(buffer));
        printf("%s\n", buffer);
    }
    else
    {
        // 创建失败
    }

    return 0;
}

以上就可以知道两个父子进程之间是如何通信的。

  • 命名管道FIFO的使用

linux系统中有shell命令可以创建这个管道mkfifo,这也是一个shell命令,也是linux系统提供的一个函数,意思是可以在进程中创建一个管道文件,mkfifo()第一个参数是创建的路径,第二个参数是权限,返回值是成功返回0,失败返回-1,但是这个函数不能创建已有的文件。

  • 也可以写两个程序来实现读写,read函数是会阻塞的,没有数据会一直等待你的写入
  • 在管道文件中不能进行光标的移动

int main()
{
    // 创建管道文件
    mkfifo("/tmp/fifo", 0777);

    // 打开文件
    int fifo_fd = open("/tmp/fifo", O_RAWR);

    // 缓冲区
    char buffer[20] = {'\0'};

    // 接收子进程的状态
    int state;

    // 创建子进程
    int child_pid = fork();

    if (child_pid > 0)
    {
        // 父进程执行语句,写入数据
        strcpy(buffer, "hello");
        write(fifo_fd, buffer, sizeof(buffer));
        // 等待子进程结束
        wait(&state);
    }
    else if (child_pid == 0)
    {
        // 子进程执行语句,读取数据
        read(fifo_fd, buffer, sizeof(buffer));
        printf("%s\n", buffer);
    }
    else
    {
        // 创建失败
    }

    return 0;
}

在linux系统中,一个管道文件的大小是4M,一共是8组512kb。使用shell命令,dh -h,就可以查看磁盘的使用情况,如果写满了write()会处于阻塞状态,如果读空了read()会处于阻塞状态

posted @ 2024-05-28 10:22  wuju  阅读(59)  评论(0)    收藏  举报