煅汾付 发表于 2025-6-11 15:26:20

管道通信

管道通信

Linux系统提供了一种通信方式,名字叫做管道通信,顾名思义,管道是单向的,比如水管、燃气管道等,换个说法就是管道是采用半双工通信的,也就是同一时刻只能完成发送数据或者接收数据。
匿名管道

用匿名管道实现,创建匿名管道,在子进程中将I am child,hello!!!写入管道,在父进程中读取管道内容并输出
/******************************************************
*
*filename:pipe
*author:zzlyx1239@126.com
*function:进程间通信
*date    :2025.4.1
*brief   :匿名管道
*note    :none
*
*CopyRight zzlyx1239@126.com 2025.4.1
***********************************************************/

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main()
{
    //1.创建一个匿名管道
    int pipefd={0};
    int ret=pipe(pipefd);
    if(ret=-1)
    {
      fprintf(stderr,
            "creat pipe error,errno=%d,%s/n",
            errno,stderror(errno));
      return -1;
    }

    //2.创建子进程
    int child_pid=fork();
    //3.分析当前id是父进程or子进程or创建失败
    if(child_pid>0)//父进程
    {
      char recebuf={0};
      read(pipefd,recebuf,sizeof(recebuf));
      printf("I am parent,my child say :%s\n",recebuf);
      wait(NULL);
    }
    else if(child_pid=0)
    {
      char sentbuf="I am child,hello!!!";
      write(pipefd,sentbuf,strlen(sentbuf));

    }
    else
    {
      fprintf(stderr, "fork error,errno:%d,%s\n",errno,strerror(errno));
                exit(2); //exit函数可以终止进程,并把进程的终止状态提供给该进程的父进程
    }

    return 0;

}命名管道

由于匿名管道只适合一对一、并且具有亲缘关系的进程间通信,导致局限性较大,所以Linux系统下还提供了另一种管道,名称叫做命名管道,也可以称为有名管道、具名管道等。
相比于匿名管道而言,命名管道有自己的文件名,可以被open,同样也支持read/write访问。当然,管道文件毕竟不是普通文件,由于管道的特性的原因,所以管道是不支持指定位置读取数据的,也就意味着不能对管道文件进行lseek操作。
/******************************************************
*
*filename:fifo
*author:zzlyx1239@126.com
*function:进程间通信
*date    :2025.4.1
*brief   :匿名管道
*note    :none
*
*CopyRight zzlyx1239@126.com 2025.4.1
***********************************************************/
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

int main()
{
    //1.创建一个命名管道,文件名为fifo,权限为0664
    int ret =mkfifo("./fifo",0664);
    if(ret=-1)
    {
      fprintf(stderr, "fifo error,errno:%d,%s\n",errno,strerror(errno));
                exit(1); //exit函数可以终止进程
    }
    //2.打开命名管道文件
    int fifo_fd =open("./fifo",O_RDWR);
    if(fifo_fd=-1)
    {
      fprintf(stderr, "open fifo error,errno:%d,%s\n",errno,strerror(errno));
                exit(1); //exit函数可以终止进程
    }
    //3.向有名管道写入数据
        ret = write(fifo_fd,"hello world",11);
        if(ret != 11)
        {
                printf("write error\n");
                return -1;
        }

        //4.关闭有名管道
        close(fifo_fd);

        return 0;
}在 /tmp 目录下创建一条命名管道,命名管道的名称用户决定,然后设计两个程序,要求进程A获取当前系统时间(time-->ctime)并写入到命名管道,进程B从命名管道中读取数据并存储在一个名字叫做log.txt的文本中。
psB.c
/******************************************************
*
*filename:psB.c
*author:zzlyx1239@126.com
*function:
*date    :2025.4.1
*brief   :取管道中的数据写入日志文件中
*note    :none
*
*CopyRight zzlyx1239@126.com 2025.4.1
***********************************************************/
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>

int main()
{
    //1.打开一个日志文件,文件名为log.txt
    FILE * log_fp=fopen("./log.txt","wb+");
    if(log_fp=NULL)
    {
      fprintf(stderr, "open log.txt error,errno:%d,%s\n",errno,strerror(errno));
                exit(1); //exit函数可以终止进程
    }
    //2.打开命名管道文件
    FILE * fifo_fp =open("./fifo","r+");
    if(fifo_fp=NULL)
    {
      fprintf(stderr, "open fifo error,errno:%d,%s\n",errno,strerror(errno));
                exit(1); //exit函数可以终止进程
    }
    //3.向有名管读取时间,写入log.txt
    while(1)
    {
      char timebuf={0};
      fread(timebuf,sizeof(timebuf),1,fifo_fp);
      fwrite(timebuf,sizeof(timebuf),1,log_fp);
      bzero(timebuf,sizeof(timebuf));
      sleep(1);
    }

        //4.关闭有名管道,关闭log.txt文件
        close(fifo_fp);
    fclose(log_fp);
        return 0;
}psA.c
/******************************************************
*
*filename:psA.c
*author:zzlyx1239@126.com
*function:
*date    :2025.4.1
*brief   :向命名管道中写入系统时间
*note    :none
*
*CopyRight zzlyx1239@126.com 2025.4.1
***********************************************************/
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

int main()
{
    //1.创建一个命名管道,文件名为fifo,权限为0664
    int ret =mkfifo("./fifo",0664);
    if(ret=-1)
    {
      fprintf(stderr, "fifo error,errno:%d,%s\n",errno,strerror(errno));
                exit(1); //exit函数可以终止进程
    }
    //2.打开命名管道文件
    int fifo_fd =open("./fifo",O_RDWR);
    if(fifo_fd=-1)
    {
      fprintf(stderr, "open fifo error,errno:%d,%s\n",errno,strerror(errno));
                exit(1); //exit函数可以终止进程
    }
    //3.向有名管道写入数据
    char * ptime;
    while(1)
    {
      ptime=ctime(time(NULL));
      write(fifo_fd,ptime,strlen(ptime));
      sleep(1);
    }
        //4.关闭有名管道
        close(fifo_fd);

        return 0;
}
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

乳杂丫 发表于 2025-10-16 16:43:52

过来提前占个楼

荏牌 发表于 2025-11-24 05:32:48

不错,里面软件多更新就更好了

滕佩杉 发表于 2025-12-7 11:14:23

感谢发布原创作品,程序园因你更精彩

艺轫 发表于 2026-1-2 19:41:38

热心回复!

韶侪 发表于 2026-1-12 14:00:14

yyds。多谢分享

锑砖 发表于 2026-1-17 20:03:59

用心讨论,共获提升!

缄戈 发表于 2026-1-20 13:17:55

谢谢楼主提供!

喜及眩 发表于 2026-1-21 07:12:36

这个好,看起来很实用

明思义 发表于 2026-1-22 06:50:22

喜欢鼓捣这些软件,现在用得少,谢谢分享!

请蒂 发表于 2026-1-23 07:20:27

前排留名,哈哈哈

班嘉淑 发表于 2026-1-26 11:43:42

收藏一下   不知道什么时候能用到

寇秀娟 发表于 2026-1-28 06:22:00

感谢分享

澹台吉星 发表于 2026-1-30 05:04:03

谢谢分享,试用一下

勺缓曜 发表于 2026-1-30 14:25:31

热心回复!

厌外 发表于 2026-2-5 08:33:36

喜欢鼓捣这些软件,现在用得少,谢谢分享!

章绮云 发表于 2026-2-8 00:22:00

感谢,下载保存了

饮邺谲 发表于 2026-2-8 09:07:37

这个好,看起来很实用

当贵 发表于 2026-2-9 08:10:54

鼓励转贴优秀软件安全工具和文档!

拙因 发表于 2026-2-10 21:50:50

懂技术并乐意极积无私分享的人越来越少。珍惜
页: [1] 2
查看完整版本: 管道通信