linux系统编程---进程间的通信--管道介绍---学习和记录(一)

进程间的通信(IPC),是指在不同进程之间传播或交换信息                                                            IPC的方式通常有管道(无名管道和命名管道),消息队列,信号量,共享储存,Socket、Streams等,其中Socket、Streams支持两台PC机上的两个进程

单机通信:如果是在一台机器上,则为单机通信 ,如半双工管道,全双工管道,消息队列,信号量,共享内存
多机通信:在多台机器上进行通信,网络通信,如Socket(套接字)、Streams等;

管道:通常是指无名管道因为没有文件名,所以叫无名管道

特点:
1、它是半双工的(
即数据只能在一个方向上流动,一个写一个读),具有固定的读端和写端。
2、它只能用于具有亲缘关系的进程之间的通信(也是
父子进程或者兄弟进程之间)。
3、它可以看成是一种特殊的文件,对于它的读写也可以使用普通的read、write 等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且
只存在于内存中。
4、
管道中的数据被读走了,管道中就没有数据了

函数原型:无名管道

#include <unistd.h>
int pipe(int pipefd[2]);//pipe函数成功返回0,失败返回-1
当建立一个管道时,由参数fd返回两个文件描述符:fd[0]为读而打开,fd[1]为写而打开,
fd[1]的输出是fd[0]的输入,管道是建立在内核之中的

关闭管道:fd[0]和fd[1]的文件描述符关闭即可

函数例子:在读fd[0]时要关闭写(fd[1]) 写fd[1]时要关闭读fd[0]

#include <stdio.h>
#include <unistd.h>
#include <string.h>
//int pipe(int pipefd[2]);
int main()
{
    int fd[2];
    int pid;
    char buf[128] = {0};
    if(pipe(fd) == -1){            //等于-1表示失败
        printf("creat pipe fail\n");
    }
    pid = fork();                  //创建进程
    if(pid < 0){                   //创建进程失败
        printf("creat pid fail\n");
    }
    else if(pid > 0){             //进入父进程
        printf("this is father\n");
        close(fd[0]);             //关闭读
        write(fd[1],"hello world",strlen("hello world")); //往fd[1]写字符串hello world
    }
    else{                        //进入子进程
        printf("this is child\n"); 
        close(fd[1]);           //关闭写
        read(fd[0],buf,128);    //将父进程中写入的字符串从fd[0]中读出来
        printf("read father %s\n",buf); //打印
    }
    return 0;
}

有名管道(文件类型):有名管道也叫命名管道,是在文件系统目录中存在一个管道文件中,管道文件仅仅是文件系统中的标示,并不在磁盘上占据空间。在使用时,在内存上开辟空间,作为两个进程数据交互的通道。

函数原型:

#include <sys/types.h>
#include <sys/stat.h>   
int mkfifo(const char *pathname, mode_t mode); 
mkfifo函数成功返回0,失败返回-1

mode:和open函数中的权限相似(0600)
pathname:路径名字

函数例子:创建管道

	#include <sys/types.h>
    #include <sys/stat.h> 
    #include <stdio.h> 
    if((mkfifo("./file",0600) == -1) && errno != EEXIST){ // EEXIST 表示文件存在错误
        printf("mkfifom fail\n");
        perror("why");
    }
函数创建成功后不会打印错误信息

函数例子:一个文件是将数据写入管道,另一个文件是将第一个写入管道中的数据读出来,然后输出

将管道中的文件读到buf中,再输出
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
//int mkfifo(const char *pathname, mode_t mode);
int main()
{
    char buf[30] = {0};
    int nread = 0;
    int cnt = 0;
    if((mkfifo("./file",0600) == -1) && errno != EEXIST){ //创建管道
        printf("mkfifom fail\n");
        perror("why");
    }
    int fd = open("./file",O_RDONLY);  //以只读方式打开管道
    printf("open success\n");
    while(1){
        nread = read(fd,buf,30);      //将管道中的数据读到buf中
        printf("read %d byte  read file:%s\n",nread,buf); //打印字节数和读出的内容
        cnt++;
        if(cnt == 5){
                break;
        }
    }
    close(fd);  //关闭管道
    return 0;
}
这里如果运行read的话会造成read堵塞,因为只读open要阻塞到某个其他进程为写而打开此管道,
这里要运行write时,read才不会堵塞
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
int main()
{
    int cnt = 0;
    char *str = "hello world";   //要向管道写入的字符串
    int fd = open("./file",O_WRONLY); //以只写的方式打开管道
    printf("write open success\n");
    while(1){                       //连续输入5个
        write(fd,str,strlen(str));  //将字符串str写入管道fd
        sleep(1);                   //延时一秒
        cnt++;
        if(cnt == 5){
              break;
        }
    }
    close(fd);                   //关闭管道
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值