您好,欢迎来到五一七教育网。
搜索
您的当前位置:首页进程间通信方式命名管道

进程间通信方式命名管道

来源:五一七教育网


没有血缘关系的进程之间是如何做到通信的?
管道应用的一个就是只能在具有共同祖先(具有亲缘关系)的进程间通信。
如果我们想在不相关的进程之间交换数据,可以使用FIFO文件来做这项工作,它经常被称为命名管道。
命名管道是一种特殊类型的文件。用命名管道通信。
mkfifo

命名管道也可以从程序里创建,相关函数有:int mkfifo(const char *filename,mode_t mode);
创建好管道之后,要让进程之间能过通信,而进程能够通信的本质是看到同一份资源!要让不同进程看到同一个命名管道文件
再打开文件时怎么知道打开的是同一个文件?同一路径下同一个文件名 = 路径+文件名。路径+文件名有唯一性。
不同进程之间通信就是两个启动的程序进行通信,形成两个程序,在程序中用函数创建一个管道文件调用mkfifo函数,而管道文件只需要创建一次就可以了。然后要考虑让两个进程都看见同一个通信信道管道文件。进程要通信先创建管道。两个进程通信一个为服务端一个为客户端,服务端为客户端提供服务,管道由服务端创建,但是在建立管道之后,只是将信道建立好了,服务方不能立即打开文件,因为写方没有向管道文件中写入数据,那么服务端就会阻塞,要等待客户端写入之后服务端才开始打开文件然后读取客户端给服务端发送的数据。

头文件方法实现,建立管道文件和删除管道文件放在了头文件中实现,当建立好管道文件之后两个进程都能拿到,当一个文件刚被建立时有文件权限
comm.hpp

#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include <string>
#include <cerrno>
#include <cstring>
#include <cstdlib>

#define FIFO_FILE "./myfifo"  //打开文件
#define MODE 06   //打开文件的之后该文件的权限
using namespace std;

//枚举打开文件
enum
{
    FIFO_CREATE_ERR = 1,
    FIFO_DELETE_ERR,
    FIFO_OPEN_ERR
};

class Init
{
public:
    Init()
    {
         //创建管道文件
        int n = mkfifo(FIFO_FILE,MODE);
        //管道文件返回值<0则创建管道文件失败
        if(n==-1)
        {
            perror("mkfifo");
            exit(FIFO_CREATE_ERR);
        }

    }

    ~Init()
    {

        int m = unlink(FIFO_FILE);
        if (m == -1)
        {
            perror("unlink");
            exit(FIFO_DELETE_ERR);
        }
    }
       
};

删除管道文件用unlink

#include<iostream>
#include"comm.hpp"


int main()
{
   Init init;

    //创建成功之后就什么都不做
    //这个管道文件已经创建成功了,然后要进行通信

    //创建管道文件之后,由客户端向管道中写入数据,然后由服务端来解析提供服务
    int fd = open(FIFO_FILE,O_RDONLY);// 等待写入方打开之后,自己才会打开文件,向后执行, open 阻塞了!

    if(fd<0)
    {
        perror("open");
        exit(FIFO_OPEN_ERR);
    }

    cout<<"server open file"<<endl;

        //通信信道打开之后就开始通信
      // 开始通信
    while (true)
    {
        char buffer[1024] = {0};
        int x = read(fd, buffer, sizeof(buffer));
        if (x > 0)
        {
            buffer[x] = 0;
            cout << "client say# " << buffer << endl;//对于从客户端拿到的数据分析或者打印
        }
        else if (x == 0)
        {
           // log(Debug, "client quit, me too!, error string: %s, error code: %d", strerror(errno), errno);
            break;
        }
        else
            break;
    }

    close(fd);
    return 0;
}

客户端,向管道文件中写入数据,但是要当服务端将信道建立之后才能往信道中写入数据进行通信
client.cc

#include<iostream>
#include"comm.hpp"

using namespace std;

int main()
{
    int fd = open(FIFO_FILE,O_WRONLY);//客户端以写的方式打开这个管道文件
    if(fd < 0)
    {
        perror("open");
        exit(FIFO_OPEN_ERR);
    }

    cout << "client open file done" << endl;
    string line;

    while(true)
    {

        cout<<"Please enter@ ";
        getline(cin,line);

        //客户端向这个管道文件中写入数据,然后让服务端来读取
        write(fd,line.c_str(),line.size());
    }
    close(fd);
    return 0;
}

不能先执行客户端

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 517ttc.cn 版权所有 赣ICP备2024042791号-8

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务