Linux 学习笔记15 管道

Linux 学习笔记15 管道

在 linux IPC (进程间通信)中,管道通信又有三种类型,分别为标准流管道,无名管道和有名管道。

  • 标准流管道
FILE* popen(const char* command, const char* open_mode); 
int pclose(FILE* fp);`

函数 popen():允许一个程序将另一个程序作为新进程来启动,并可以传递数据给它或者通过它接收数据。
command 字符串是要运行的程序名。
open_mode 必须是“r”或“w”。
如果 open_mode 是“r”,被调用程序的输出就可以被调用程序(popen)使用,调用程序利 popen 函数返回的 FILE*文件流指针,就可以通过常用的 stdio 库函数(如 fread)来读取被 调用程序的输出;如果 open_mode 是“w”,调用程序(popen)就可以用 fwrite 向被调用程序发送数据,而被调用程序可以在自己的标准输入上读取这些数据。
popen原理如下:
popen
例:

#include <func.h>
//标准流管道
//
int main()
{
    FILE *fp;
    fp=popen("./print","r");                                                                                  
    //fp=popen("ls -l","r");//for test command也可以是命令 ls -l
    ERROR_CHECK(fp,NULL,"popen");
    char buf[1024]={0};
    fread(buf,sizeof(char),sizeof(buf),fp);
    printf("popen:%s",buf);
    pclose(fp);
    return 0;
}

print函数如下:

#include <func.h>

int main()
{
    printf("I am print elf\n");                                                                               
    return 0;
}

执行效果如下:

popen_r

  • 无名管道pipe
    管道实际是内核开辟了一段大小为4K的缓冲区,进程A和B都能往缓冲区里读写。
    因此,进程间通信都要借助内核来实现。
    无名管道的原理、特点,方法如下所示:
  • int fds[2]
    pipe(fds);
    读端fds[0],写端fds[1]
    一旦fork(),父子进程都有管道的读写端。
    使用时会让一端写一端读。如果想要双向通信,则需要两条管道,int fdss[2]
    因此无名管道具有如下特点:
    1 只能在亲缘关系进程间通信
    2 半双工(固定的读端和固定的写端)
    3 他是特殊的文件,可以用 read、write 等,只能在内存中
#include <func.h>                                                                                             

int main()
{
    int fds[2];
    pipe(fds);//无名管道
    printf("fd[0]=%d,fds[1]=%d\n",fds[0],fds[1]);
    //默认fds[0]为读端,fds[1]为写端
    if(!fork())
    {   
        close(fds[1]);//假设子进程读,关闭写端
        char buf[128]={0};
        read(fds[0],buf,sizeof(buf));
        printf("Child Mark3 buf=%s\n",buf);
        exit(0);
    }   
    else
    {   
        close(fds[0]);//父进程写,关闭读端
        write(fds[1],"hello",5);
        wait(NULL);
        return 0;
    }   
}

执行结果如下:
pipe

  • 有名管道
    int mkfifo(const char *pathname, mode_t mode);
    参数解析
    pathname 为要创建的 FIFO 文件的全路径名;
    mode 为文件访问权限mkfifo
#include <func.h>
//创建一个命名管道文件
int main(int argc,char*argv[])
{
    ARGS_CHECK(argc,2);
    int ret;
    ret=mkfifo(argv[1],0666);//权限为0664                                                                     
    ERROR_CHECK(ret,-1,"mkfifo");
    return 0;
}

执行结果如下:

mkfifo

  • 删除FIFO文件的函数原型为:
    int unlink(const char *pathname);
    代码如下:
#include <func.h>

int main(int argc,char*argv[])
{
    ARGS_CHECK(argc,2);
    int ret;
    ret=unlink(argv[1]);                                                                                      
    ERROR_CHECK(ret,-1,"unlink");
    return 0;
}

执行效果如下:

unlink

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值