从零开始学习Linux(11)----进程间通信(管道)

1.引言

        两个进程之间,可以进行数据的直接传递吗?不能!进程具有独立性

1.为什么??

  • 数据传输:一个进程需要将它的数据发送给另一个进程
  • 资源共享:多个进程之间共享同样的资源
  • 通知事件:一个进程需要向另一个或一组进程发送消息,通知它们发生了某种事件(如进程终止时要通知父进程)
  • 进程控制:有些进程希望完全控制另一个进程的执行(如调试进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变

        往往需要多个进程协同,共同完成一些事情

2.是什么

        一个进程把自己的数据,能够交给另一个进程。

3.怎么办??

        a.一般规律

        进程间通信的本质:先让不同的进程,看到同一份资源(一般都是要由OS提供)

  1. 交换数据的空间(内存)
  2. 不能由通信双方任何一个提供!

        b.具体做法

        OS提供的空间有不同的样式,就决定了有不同的通信方式

  1. 管道(匿名,和命名):基于文件的,让不同进程看到同一份资源的通信方式,叫做管道!管道只能被设计成为单向通信
  2. 共享内存
  3. 消息队列
  4. 信号量

2.管道

        管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用(通常是一个父进程和它的子进程)。管道的实质是一个内核缓冲区,进程以先进先出(FIFO)的方式从缓冲区存取数据:管道一端的进程顺序地将进程数据写入缓冲区,另一端的进程则顺序地读取数据。

        匿名管道:可以(只能)进行具有血缘关系的进程,进行进程间通信

代码测试如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
void writer(int wfd)
{
    const char* str="hello father,I am child";
    char buffer[128];
    int cnt=0;
    pid_t pid=getpid();
    while(1)
    {
        snprintf(buffer,sizeof(buffer),"message:%s,pid:%d,count:%d",str,pid,cnt);
        write(wfd,buffer,strlen(buffer));
        cnt++;
        sleep(1);
    }
}
void reader(int rfd)
{
    char buffer[1024];
    while(1)
    {
        ssize_t n=read(rfd,buffer,sizeof(buffer)-1);
        (void)n;
        printf("father get a message %s",buffer);
    }
}
int main()
{
    int pipefd[2];
    int n=pipe(pipefd);
    if(n<0) return 1;
    printf("pipefd[0]:%d,pipefd[1]:%d\n",pipefd[0],pipefd[1]);//3,4

    pid_t id=fork();
    if(id==0)
    {
        //child:r
        close(pipefd[0]);

        writer(pipefd[1]);

        exit(0);
    }
    //father:w
    close(pipefd[1]);

    reader(pipefd[0]);

    wait(NULL);
}

a.4种情况

  1.  管道内部没有数据&&子进程不关闭自己的写端文件fd,读端(父)就要阻塞等待,直到pipe有数据
  2. 管道内部被写满&&父进程(读端)不关闭自己的fd,写端(子)写满之后,就要阻塞等待
  3. 对于写端而言:不写了&&关闭了pipe,读端会将pipe中的数据读完,最后就会读到返回值为0,表示读结束,类似读到了文件的结尾
  4. 读端不读&&关闭,写端在写,OS会直接终止写入的进程(子进程),通过信号13)SIGPIPE 信号杀掉进程

b.5种特性

  1. 自带同步机制
  2. 血缘关系进程进行通信,常见于父子
  3. pipe是面向字节流的
  4. 父子退出,管道自动释放,文件的生命周期是随进程的
  5. 管道只能单向通信,半双工的一种特殊情况
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值