IPC——管道

进程间通信(IPC)
英文名IPC,因为每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户地址空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信。
这里写图片描述
管道
管道是Unix中最古老的进程间通信的形式,是一种最基本的IPC机制。
我们把从一个进程连接到另一个进程的数据流称为一个“管道”。
特点:
(1)只能用于有公共祖先的进程之间通信。
(2)管道提供流式服务
(3)生命周期随进程
(4)内核会对管道进行同步与互斥
(5)管道是半双工的,需要双方通信时,须建立两个管道。
匿名管道

#include<unistd.h>
int pipe(int  fd[2]);
//成功返回0,失败返回错误代码

fd[0]为读而打开,fd[1]为写而打开
fd[1]的输出是fd[0]的输入。
单个进程中的管道几乎没有任何用处。管道只能在具有公共祖先的两个进程之间使用。通常,一个管道由一个进程创建,在进程调用fork之后,这个管道就能在父进程和子进程之间使用了。

父进程调用pipe开辟管道,得到两个文件描述符指向管道的两端,父进程调用fork创建了子进程,子进程也有两个文件描述符指向同一管道。
因为管道是单向通信的,所以父进程关闭写端,子进程关闭读端。子进程可以往管道里写,父进程可以在管道里读。
这里写图片描述
代码实现:

#include<stdio.h>
#include<unistd.h>
#include<string.h>
int main()
{
    //(1)进程创建管道
    int fds[2] = {0,0};
    int ret = pipe(fds);
    if(ret < 0)
    {
       perror("pipe");
       return 1;
    }
    //(2)创建子进程
    pid_t  id = fork();
    //父进程关闭写端,子进程关闭读端
    if( id == 0)//子进程——>写
    {
      close(fds[0]);
      char* msg = "hello father,I am your child";
      while(1)
      {
        write(fds[1],msg,strlen(msg));
        sleep(1);
      }
    }
    else//父进程——>读
    {
      char buf[1024];
      close(fds[1]);
      while(1)
      {
        ssize_t s = read(fds[0],buf,sizeof(buf)-1);
        if(s > 0)
        {
            buf[s] = 0;
            printf("%s\n",buf);
        } 
    }
      }
      return 0;
}  
[a@localhost ~]$ ./a.out
hello father,I am your child
hello father,I am your child
hello father,I am your child
hello father,I am your child

命名管道
匿名管道只能用于有血缘关系的进程。命名管道(FIFO)的提出就突破了管道的限制,它可以以不同的方式方法调用(可以跨平台,跨语言,跨权限),只要知道命名管道的名字,发送到命名管道的信息可以被一切拥有指定授权的程序读取。

创建:

//(1)命令行上创建
$ mkfifo filename
//从程序里创建
int mkfifo(const char *filename,mode_t mode);//成功返回0,失败返回-1

创建命名管道

int main(int argc, char *argv[])
{
    mkfifo("p2",0644);
    return 0;
}
#include<stdio.h>
#include<sys/stat.h>

int main()
{
   int ret = mkfifo("./myfifo",0666);
   if(ret < 0)
   {
      perror("mkfifo");
      return 1;
   }
   printf("mkfifo ok\n");
   return 0;
}
[a@localhost ~]$ gcc fifo.c
[a@localhost ~]$ ./a.out
mkfifo ok

用命名管道实现server&client通信
server.c
这里写图片描述
client.c
这里写图片描述
makefile
这里写图片描述
结果:
这里写图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值