进程通信之对象-有名管道

由于无名管道的缺点,从而产生有有名管道(管道=队列):在系统中存在这样一个文件节点。

作用:实现非父子或有亲缘关系的进程之间的通信。
【注】只有文件节点不占磁盘空间的有:有名管道,字符设备,块设备,套接字。
例子1:有名管道的创建,调用mkfifo()函数。

#include"stdio.h"
#include"unistd.h"
#include"stdlib.h"

int main()
{
    int ret;
    ret = mkfifo("./mkfifo",0777);
    if(ret<0)
    {
    printf("create mkfifo failure\n");
    return -1;
    }
    printf("create mkfifo success\n");
    return 0;
 }

图成功创建有名管道mkfifo文件,其权限于umask有关系。

【注】mkfifo并不是生成于内核里,而是用户空间里的节点,当进程调用open函数打开mkfifo文件时,才会在内核空间生成一个管道缓存。

例子2:基于例子1,通过有名管道实现两个无亲缘关系的进程之间的通信。建立两个进程process_1.c, process_2.c;分别打印5次first和second,第一个进程先打印,第二个进程后打印。即当第一个进程打印完后通过有名管道告诉第二个进行,然后第二个进程开始打印。
1)由于mkfifo已经创建好,进程process_1利用open()函数打开mkfifo,打印5条语句之后。向管道写入'1',代表process_2可以打印了;
process_1.c文件:
`

#include"stdio.h"
#include"unistd.h"
#include"fcntl.h"
#include"stdlib.h"

int main()
{
        int fd;
        int process_inter=0;
        fd = open("./mkfifo",O_WRONLY);//打开生成的mkfifo文件后,在内核生成有名管道
        if(fd<0)
        {
        printf("open mkfifo failure\n");
        return -1;
        }
        printf("open mkfifo success\n");
        
        int i;
        for(i=0;i<5;i++)//打印5次
        {
        printf("first\n");
        }

        sleep(5);//睡眠5秒
        process_inter = 1;//信号制为1
        write(fd,&process_inter,1);//1写入有名管道
        close(fd);//关闭管道
        while(1);//进入死循环,确保进程不会结束
        return 0;
}

进程process_2.c的内容:

#include"stdio.h"
#include"unistd.h"
#include"fcntl.h"
#include"stdlib.h"

int main()
{
        int fd;
        int process_inter=0;
        fd = open("./mkfifo",O_RDONLY);//打开管道
        if(fd<0)
        {
        printf("open mkfifo failure\n");
        return -1;
        }
        printf("open mkfifo success\n");
        
        read(fd,&process_inter,1);//读取管道中进程process_1的信息,即刚才进程process_1写进管道的1
        while(process_inter==0);//若是读取不到刚才进程process_1写进管道的1,则进入死循环,不执行以下语句
        int i;
        for(i=0;i<5;i++)
        {
        printf("first\n");
        }
        close(fd);//关闭通道
        while(1);   //确保进程不会先结束
        return 0;
}

编译进程,并打开两个窗口,先运行process_1,后运行process_2,运行结果输出如图;

process_1运行打印first后,睡眠5秒后,制process_inter=1;此时,process_2读取信号1,并打印输出;

以上例子与讲解,说明了有名管道可实现非亲缘关系进程间的通信。

发布了26 篇原创文章 · 获赞 11 · 访问量 591

猜你喜欢

转载自blog.csdn.net/weixin_38251305/article/details/103913397