四、Linux--管道

    xiaoxiao2021-12-14  16

    1无名管道pipo()

    #include<unistd.h>

    int pipe(int filedes[2]);

     

    返回值:成功,返回0,否则返回-1

    参数数组包含pipe使用的两个文件的描述符。fd[0]:读管道,fd[1]:写管道。

    功能:创建一个无名管道

    必须在fork()前调用pipe(),否则子进程不会继承文件描述符。两个进程不共享祖先进程,就不能使用pipe。但是可以使用命名管道。

    说明

    管道是一种把两个进程之间的标准输入和标准输出连接起来的机制,从而提供一种让多个进程间通信的方法,当进程创建管道时,每次都需要提供两个文件描述符来操作管道。其中一个对管道进行写操作,另一个对管道进行读操作。对管道的读写与一般的IO系统函数一致,使用write()函数写入数据,使用read()读出数据。

    /*

    在父进程中输入输出

    */

    #include <stdio.h>

    #include <unistd.h>

    int main(int argc,char *argv[])

    {

        pid_t pid;

        int fd[2];

        int fd1[2];

        int buf[1024];

        int i,ii;

        i = pipe(fd);//生成无名管道

    if(i < 0)

        {   

            printf("the pipe0 set fail!\n");

            return -1;

        }   

        ii = pipe(fd1);

        if(ii<0)

        {   

            printf("the pipe1 set fail!\n");

            close(fd[0]);

            close(fd[1]);

            return -1;

        }   

        pid = fork();生成子进程

        if(pid)//父进程

        {   

            i = 0;

            close(fd[0]);//关闭管道fd的读

            close(fd1[1]);//关闭管道fd1的写

      while(1)

            {

                i = read(STDIN_FILENO,buf,1024);//将键盘输入的数据读到buf

                if(0 == i)//ctrl d 退出

                {

                    break;

                }

                write(fd[1],buf,i);//buf数据输入到管道fd

                ii = read(fd1[0],buf,1024);将管道fd1中的数据读到buf

                write(STDOUT_FILENO,buf,ii);//buf中的数据输出到屏幕上

            }

            close(fd[1]);

            close(fd[0]);

        }

        else if(0 == pid)//子进程

        {

            close(fd1[0]);

            close(fd[1]);

            dup2(fd1[1],STDOUT_FILENO);//fd1的写文件描述符复制给STDOUT_FILENO

    //则对STDOUT_FILENO操作即是对fd1[1]操作

            close(fd1[1]);//因为一个管道有两个写,为防止出错,关闭一个写

            dup2(fd[0],STDIN_FILENO);

            close(fd[0]);

            execl("./atoA","./atoA",NULL);//调用atoA执行文件,执行过程中的标准输入输出分别表示向管道fd读,向管道fd1

        }

    }

    /*

    atoA.c

    将小写字母转换为大写字母

    */

     #include <stdio.h>

    #include <unistd.h>

    void atoA(char *buf,int n)

    {

        int i;

        for(i = 0;i<n;i++)

        {   

            if((buf[i]>='a')&&(buf[i]<='z'))

            {   

               buf[i] = buf[i]-32;

            }   

        

        }   

    }

    int main()

    {

        char buf[1024];

        int n;

        while(1)

        {   

            n = read(STDIN_FILENO,buf,1024);//向管道fd

            if(0 == n)

            {   

                break;

            }   

            atoA(buf,n);

           write(STDOUT_FILENO,buf,n); //向管道fd1

        }   

    }

    2 mkfifo()

    #include<sys/stat.h>

    int mkfifo(const char * pathname,mode_t mode);

    功能:创建一个有名管道

    mkfifo ()会依参数pathname建立特殊的FIFO文件,该文件必须不存在,而参数mode为该文件的权限。建立的FIFO文件其他进程都可以用读写一般文件的方式存取。

    返回值

    若成功则返回0,否则返回-1,错误原因存于errno中。

    错误代码:

    EACCESS 参数pathname所指定的目录路径无可执行的权限

    EEXIST 参数pathname所指定的文件已存在。

    ENAMETOOLONG 参数pathname的路径名称太长。

    ENOENT 参数pathname包含的目录不存在

    ENOSPC 文件系统的剩余空间不足

    ENOTDIR 参数pathname路径中的目录存在但却非真正的目录。

    EROFS 参数pathname指定的文件存在于只读文件系统内。

    转载请注明原文地址: https://ju.6miu.com/read-968984.html

    最新回复(0)