进程间通信--命名管道

几个术语
  • 二义性:当我们往一个管道里面写端写数据的时候,比如写一个hello的时候,当我们写到he的时候,读端就已经开始读取数据了,所以这是不对的,这就是二义性
  • 临界资源:多个流可以访问的一个共同的存储资源
  • 临界区:访问临界资源的代码叫做临界区
  • 互斥:任一时候只能有一个进程利用临界资源访问临界区,并且是以原子性访问
  • 原子性:要么访问,要么没有访问,不存在正在访问的情况
  • 饥饿问题:一个进程因为级别低,在某些场景之下要求访问某一资源的时候一直访问不了,这就出现了饥饿问题
  • 同步:按照某一顺序访问临界资源

命名管道

命名管道的概念

匿名管道(pipe)的一个不足之处就是,匿名管道只能用于具有血缘关系的进程之间的通信,但是进程间通信的时候有很多时候都不是具有血缘关系的,这个时候就需要其他的一些通信方式,然后就有了命名管道。 命名管道通过一个路径将各个进程相连,只要一个进程能够访问某一个路径就能够访问这个管道了

命名管道的创建和读写

在shell下面我们可以使用mknod和mkfifo来创建管道

这里我们经常使用的是mkfifo,所以只是简单的介绍一个mkfifo,另一个就不做详细的介绍了
我们在shell下可以使用mkfifo myfifo.pipe来创建一个命名管道,然后在记住他的路径,在使用的时候,我们可以直接通过open来打开一个管道进行读写的 操作

下面的是程序中使用的mkfifo函数,先看接口原型

#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *filename, mode_t mode);

解释一些返回值和参数,创建成功返回0,失败返回-1。
参数中const char *filename,就是一个路径加上文件名的形式,mode_t mode是我们创建的这个管道的操作权限,我们可以是设置为0666 | S_IFIFO,如下的使用方式,其中的S_IFIFO是一个固定的操作命名管道的一种方式,这里先不用管   

我们在函数中可以按照如下的使用

if(fifo("./pipe",0666 | S_IFIFO) < 0)
{
    printf("fifo error");
    return 1;
}

下面我们通过一个简单的程序实现一个写端,一个读端的操作,这个时候我们可以打开两个终端,分别运行下面的程序,就会实现进程间通信,一个写,一个读

写 端

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>

#define _PATH_ "/home/xiaoxu/code/fifo/log.pipe"

int main()
{
    umask(0);
    if(mkfifo(_PATH_,0666|S_IFIFO) < 0 )
    {
        printf("fifo error\n");
        return 1;
    }
    int fd = open(_PATH_,O_WRONLY);
    if(fd <= 0)
    {
        printf("open error\n");
        return 1;
    }
    else
    {
        char buf[100];
        memset(buf,'\0',sizeof(buf));
        while(1)
        {
            scanf("%s",&buf);
            int wr = write(fd,buf,sizeof(buf));
            if(wr <= 0)
            {
                printf("write error\n");
                break;
            }
        }

    }
    close(fd);
    return 0;
}

读端

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>

#define _PATH_ "/home/xiaoxu/code/fifo/log.pipe"

int main()
{
    int fd = open(_PATH_,O_RDONLY);   //只读方式打开一个管道
    if(fd < 0)    //打开管道失败
    {
        printf("read error\n");
        return 1;
    }
    else   //打开管道成功
    {
        char buf[100];
        memset(buf,'\0',sizeof(buf));
        while(1)
        {
            int red = read(fd,buf,sizeof(buf));  //把管道里面的内容读取到buf中,所以上面应该加上memset这个函数,对buf进行初始化
            if(red <= 0)   //
            {
                printf("read error\n");
                break;
            }
            printf("%s\n",buf);
        }
        close(fd);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值