管道

通常将一个进程的输出通过管道连接到另一个进程的输入,linux下已经对shell命令里管道符号“|”太熟悉了,起到了命令连接的作用,比如命令

[lihui@localhost ~]# lspci | grep Network
0b:00.0 Ethernet controller: Intel Corporation 82599EB 10-Gigabit SFI/SFP+ Network Connection (rev 01)
0b:00.1 Ethernet controller: Intel Corporation 82599EB 10-Gigabit SFI/SFP+ Network Connection (rev 01)
12:00.0 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01)
12:00.1 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01)

用户键盘的输入lspci为标准输入,这条命令就能输出一些信息,这里是标准输出,会将这些标准输出传递给grep Network作为它的标准输入,shell实际上将标准输入和标准输出进行了重新连接,使得数据流从键盘输入通过两个命令最终输出到屏幕上

管道pipe由下面函数创建:

#include <unistd.h>

int pipe(int filedes[2]);

参数是一个由两个整数类型的文件描述符组成的数组的指针,经过参数filedes返回两个文件描述符,filedes[0]以读打开,filedes[1]以写打开,而filedes[1]的输出就是filedes[0]的输入,也就是写到filedes[1]的所有数据都可以从filedes[0]里读回来,数据基于先进先出的原则处理,所以读的次序和写的次序是一致的;函数成功返回0,出错返回-1

创建一个简单的管道

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#define MAX_SIZE 20

int main(){
    int data_len;
    int filedes[2];
    char *str = "Hello world";
    char buffer[MAX_SIZE];

    memset(buffer, 0, sizeof(buffer));

    if (!pipe(filedes)){
        data_len = write(filedes[1], str, strlen(str));
        printf("Have written %d bytes\n", data_len);
        data_len = read(filedes[0], buffer, MAX_SIZE);
        printf("Have read %d bytes: %s\n", data_len, buffer);
        exit(0);
    }
    return 0;
}

运行结果:

[lihui@localhost ~]# ./a.out 
Have written 11 bytes
Have read 11 bytes: Hello world

pipe创建管道之后,通过文件描述符filedes[1]写入数据,然后再从filedes[0]读出数据,假如这时刻手痒,想看看假如从filedes[0]写数据,然后从filedes[1]读出数据,会不会报错,那就将两个文件描述符进行更换:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#define MAX_SIZE 20

int main(){
    int data_len;
    int filedes[2];
    char *str = "Hello world";
    char buffer[MAX_SIZE];

    memset(buffer, 0, sizeof(buffer));

    if (!pipe(filedes)){
        data_len = write(filedes[0], str, strlen(str));
        printf("Have written %d bytes\n", data_len);
        data_len = read(filedes[1], buffer, MAX_SIZE);
        printf("Have read %d bytes: %s\n", data_len, buffer);
        exit(0);
    }
    return 0;
}

运行结果,果然报错了:

[lihui@localhost ~]# ./a.out 
Have written -1 bytes
Have read -1 bytes: 

可见怀疑也要找没有明文规定的东西来针对~!

发表回复