当前位置:   article > 正文

【Linux】命名管道的创建方法&&基于命名管道的两个进程通信的实现

【Linux】命名管道的创建方法&&基于命名管道的两个进程通信的实现

一、匿名管道和命名管道的区别

  • 匿名管道由pipe函数创建并打开。
  • 命名管道由mkfifo函数创建,打开用open
  • FIFO(命名管道)与pipe(匿名管道)之间唯一的区别在它们创建与打开的方式不同,一但这些工作完成之后,它们具有相同的语义。

一、创建命名管道的函数

  1. #include <sys/stat.h>
  2. // 返回值:成功返回0,出错返回-1
  3. int mkfifo(const char *pathname, mode_t mode);

pathname指创建出来的管道的路径和管道名,mode指创建出来的管道的权限,这里的权限和文件的权限是一样的。

二、删除命名管道的函数

  1. #include <unistd.h>
  2. // 返回值:成功返回0,出错返回-1
  3. int unlink(const char *pathname);

pathname指创建出来的管道的路径和管道名,unlink也可以用来删除一般的文件。

三、利用命名管道实现两个进程之间的简单通信

 这个通信将实现写端发送信息读端接收信息。更多地实现细节会在代码中以注释的方式给出。

3.1、头文件

  1. #include <iostream>
  2. #include <cstring>
  3. #include <unistd.h>
  4. #include <sys/stat.h>
  5. #include <sys/types.h>
  6. #include <fcntl.h>
  7. #include <cstdio>
  8. using namespace std;
  9. #define MODE 0666 //权限
  10. #define NAME "./fifo.txt"
  11. //定义命名管道结构体
  12. class Fifo
  13. {
  14. private:
  15. string _name; // 文件路径加文件名
  16. public:
  17. Fifo(const string &name)
  18. : _name(name)
  19. {
  20. int n = mkfifo(_name.c_str(), MODE);
  21. if (n == 0)
  22. cout << "创建管道成功!" << endl;
  23. else
  24. cout << "创建管道失败!原因是:" << strerror(errno) << endl;
  25. };
  26. ~Fifo()
  27. {
  28. int n = unlink(_name.c_str());
  29. if (n == 0)
  30. cout << "删除管道成功!" << endl;
  31. else
  32. cout << "删除管道失败!原因是:" << strerror(errno) << endl;
  33. };
  34. };

3.2、接收方(Server)

  1. #include "namedPipe.hpp"
  2. int main()
  3. {
  4. Fifo fifo(NAME);
  5. //打开文件,打开成功返回文件描述符,打开失败返回-1
  6. int rfd = open(NAME, O_RDONLY);
  7. if (rfd < 0)
  8. {
  9. cout << "文件打开失败,原因是:" << strerror(errno) << endl;
  10. return 1;
  11. }
  12. cout << "文件打开成功!" << endl;
  13. while (true)
  14. {
  15. char buffer[1024];
  16. //读端不退,read函数会一直阻塞等待,读端退出read读到0
  17. ssize_t n = read(rfd, buffer, sizeof(buffer) - 1);
  18. if (n > 0)
  19. {
  20. buffer[n] = '\0';
  21. cout << "客户说:" << buffer << endl;
  22. }
  23. else if (n == 0)
  24. {
  25. cout << "客户退出了,我也退出了";
  26. break;
  27. }
  28. else
  29. {
  30. cout << "读取出错!原因是:" << strerror(errno) << endl;
  31. break;
  32. }
  33. }
  34. close(rfd);
  35. return 0;
  36. }

3.3、发送方(Client)

  1. #include "namedPipe.hpp"
  2. int main()
  3. {
  4. int wfd = open(NAME, O_WRONLY);
  5. if (wfd < 0)
  6. {
  7. cout << "文件打开失败,原因是:" << strerror(errno) << endl;
  8. return 1;
  9. }
  10. cout << "文件打开成功!" << endl;
  11. string buffer;
  12. while(true)
  13. {
  14. cout << "请输入你的信息:" << endl;
  15. getline(cin, buffer);
  16. if(buffer == "quit")
  17. break;
  18. int n = write(wfd, buffer.c_str(), sizeof(buffer)-1);
  19. if(n < 0)
  20. {
  21. cout << "输入错误,错误原因是:" << strerror(errno) << endl;
  22. }
  23. }
  24. close(wfd);
  25. return 0;
  26. }

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号