代码可以在 这里 下载

代码主要涉及到:

  • 管道通信
  • 多线程(含临界区)
  • 多进程通信
  • 创建的子进程独立运行

更新日志

04-12-2020
1. 去除自定义函数返回值,改为int作为函数返回值并增加相应的说明
2. pipe_create_win函数改名为pepe_create,用法不变
3. write函数额外增加一个参数,意义:吐出实际发送数据长度,函数的返回值表明当前调用函数状态:成功or失败
4. pipe_helper类的析构函数增加异常处理,避免析构函数出现异常而造成程序异常中断运行,内存未能释放的现象。
5. 匿名管道通信没有测试;Linux下的管道通信正在路上...... 24-09-2020
接收线程,增加创建事件 1. (18:27 15/9/2020) 增加cmake版本

lib_pipe


1. 关于

lib_pipe是一个用c++编写的管道通信动态库,截至目前(15/9/2020),完成了Windows上的收发。创建这个项目的初衷:

  • 现在有一个main程序,需要创建1个或者多个子进程,每个子进程都有自己的活儿要干,且,创建子进程时,还需要读取每个进程的配置文件
  • main程序需要支持控制子进程的退出

    之前没有做过这样的需求,都是多线程玩的嗨。弥补多进程知识....

2. 目录说明

.
├───Debug // exe的输出路径,目前,exe编译环境:win10 1909 + VS2015up3
│ ├───1 // 子进程1所需文件
│ ├───2 // 子进程2所需文件
│ └───3 // 子进程3所需文件
├───demo_create // client项目,创建一个子进程的程序
├───lib_pipe // 管道通信项目,动态库
└───main // main项目,负责调用client子进程

3. 项目说明

  • 3.1 main项目将创建子进程,新创建的子进程独立运行

  • 3.2 创建的子进程所需文件在Debug目录下的1、2和3目录

  • 3.3 main进程将与子进程采用管道通信

  • 3.4 main将发送Q通知子进程结束,子进程收到Q后,释放自己创建时申请的一些资源,再退出

  • 3.5 lib_pipe, 目前(15/9/2020)仅支持Windows,后期将持续完善,简单封装了常用操作,欢迎指正,一起完善

  • 3.6 解决方案是用VS2015 up3创建的,若尝试用低于这个版本的VS打开项目,请创建一个空的解决方案,再添加项目即可

  • 3.7 代码中使用 nullptr 关键字,请选择支持对应所需的编译器

  • 3.8 main项目和 demo_create 都使用lib_pipe, 动态库名字和目录,配置到了VS的项目属性中。因为lib输出到Debug目录下,所以将lib目录配置为:${TargetDir}

4.lib_pipe使用

按照习惯,封装了以下操作:

  • init-初始化管道信息
  • wrie-向管道写入数据
  • uninit-释放初始化申请的资源
  • on_recv_data-接收数据(单独创建了一个线程接收数据

文件,包括,lib库文件,dll动态库,和头文件,头文件名: pipe_interface.h

5. 返回值说明

注意: 04-12-2020更新中已经摒弃自定义函数返回值

c++11引入了tuple,但是当初考虑到需要兼容不支持c++11的环境,故换作了std::pair作为函数的返回值,以便能获取更多有效的信息。

之前以int为函数的返回值,通过定义各种数值对应其结果,比如0-成功,1,字符串为空,2-文件不存在之类的。

lib_pipe使用的返回值声明如下:

相关说明,请到文件按【pipe_interface.h】查看源码。

6. 接收

  • 接收需要继承类【irecv_data】,并实现函数【on_recv_data】
  • 初始化函数 init的第二个参数需要传递为继承【ipipe_interface】类的对象
  • 不需要接收,传递NULL即可

7.一个例子(非完整)

lib_pipe的用法可以在项目 main 和 demo_create中找到,包括收发。

  • 初始化
pipe_param_base base_param;
base_param._to_create_pipe = false;
base_param._name = std::string("\\\\.\\pipe\\ReadPipe");
ret_type ret_val = pipe.init(base_param);
if (0 != ret_val.id())
{
std::cout << "error id = " << ret_val.id() << ", str = " << ret_val.str().c_str() << "\n\n";
}
else
{
cout << "子进程 " << argv[0] << " 创建管道成功...\n";
}
  • 写入数据(发送)
const char arr_send[] = "Q";	/// 子进程约定收到 Q 就结束进程
for (int i = 0; i < pipe_count_3; i++)
{
cout << "\n\n正在发送:";
ret_type ret_val = pipe_arr[i].write(arr_send, sizeof(arr_send));
if (0 != ret_val.id())
cout << "i = " << i << ", 发送失败,id = " << ret_val.id() << "\n\n";
else
cout << "i = " << i << ", 发送成功,id = " << ret_val.id() << "\n\n";
}
  • 释放
pipe.uninit();
  • 接收

    接收需要重写函数 on_recv_data
void on_recv_data(const char *pdata, const unsigned int len_recv_data)
{
cout << "\n\n进程: " << str_process_name.c_str() << " 收到数据了: " << len_recv_data << "\n";
cout << "进程: " << str_process_name.c_str() << "收到的数据是:";
for (unsigned int i = 0; i < len_recv_data; i++)
{
cout << pdata[i];
}
// 约定 第一个字符为Q,退出
if ('Q' == pdata[0])
{
EnterCriticalSection(&cs_proc_is_end);
process_is_end = true;
LeaveCriticalSection(&cs_proc_is_end);
}
}

8. License

BSD licenses

9. 运行结果

windows10使用VS(VC++)创建c++多进程命名管道通信的更多相关文章

  1. Linux学习记录--命名管道通信

    命名管道通信 什么是命名管道 一个主要的限制是,它是匿名管道的应用还没有名字,因此,只有它可以用于进程间通信的方式与亲缘关系.在命名管道(named pipe或FIFO)提出后,该限制得到了克服.FI ...

  2. C++和C#进程之间通过命名管道通信(上)

    C++和C#进程之间通过命名管道通信(上) "命名管道"是一种简单的进程间通信(IPC)机制.命名管道可在同一台计算机的不同进程之间,或在跨越一个网络的不同计算机的不同进程之间,支 ...

  3. C#命名管道通信

    C#命名管道通信 最近项目中要用c#进程间通信,以前常见的方法包括RMI.发消息等.但在Windows下面发消息需要有窗口,我们的程序是一个后台运行程序,发消息不试用.RMI又用的太多了,准备用管道通 ...

  4. c# c++通信--命名管道通信

    进程间通信有很多种,windows上面比较简单的有管道通信(匿名管道及命名管道) 最近做个本机c#界面与c++服务进行通信的一个需求.简单用命名管道通信.msdn都直接有demo,详见下方参考. c+ ...

  5. linux命名管道通信过程

    前一个道,这节学习命名管道. 二命名管道 无名管道仅仅能用来在父子进程或兄弟进程之间进行通信,这就给没有亲缘关系的进程之间数据的交换带来了麻烦.解决问题就是本节要学习的还有一种管道通信:命名管道. 命 ...

  6. c#NamedPipe命名管道通信例子

    服务端 private NamedPipeServerStream pipeServer; private Thread receiveDataThread = null; public fServe ...

  7. C#使用(NamedPipe)命名管道通信的例子

    https://blog.csdn.net/yl2isoft/article/details/20228279

  8. [C#]基于命名管道的一对多进程间通讯

    在工作中碰到了一个进程间通讯的问题,大概是这样的: 项目本身是.net Core做的,但是有部分功能Core中不方便实现,有的是依赖Framework,有的是因为权限和安全问题. 那基于这个问题,问了 ...

  9. 【windows 操作系统】进程间通信(IPC)简述|无名管道和命名管道 消息队列、信号量、共享存储、Socket、Streams等

    一.进程间通信简述 每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进 ...

随机推荐

  1. P6973 [NEERC2016]List of Primes

    题目传送门. 题意简述:将质数集合的所有子集按照子集和为第一关键字,字典序为第二关键字从小到大排序,求最终形成的字符串的第 \(l\sim r\) 个字符. 在 cnblogs 内查看. 又是一道妙妙 ...

  2. Matlab指针数组

    Matlab指针数组 前面博客Matlab指针中介绍了如何在Matlab中使用handle类型对象作为指针使用,本文则介绍一些使用这些类型指针的小技巧. 自定义类型的指针数组 在大部分编程语言中,我们 ...

  3. 有限元边界 Dirichlet 条件处理

    参考自百度文档,这里只考虑 Dirichlet 边界条件情况. 有限元法基本方法就是是构造线性方程组 \[\begin{equation} Au = f \end{equation}\] 进行求解.其 ...

  4. 数据分析体系 — 用户粘性的两个计算指标(DAU/MAU和月人均活跃天数)

    很多运营都了解DAU(日活跃用户数)和MAU(月活跃用户数)的重要性,但在某些情况下这两个数值本身并不能反映出太多问题,这个时候就要引用到[DAU/MAU]的概念,即[日活/月活] 用户粘性的两个计算 ...

  5. 听老外吐槽框架设计,Why I Hate Frameworks?

    原创:微信公众号 码农参上,欢迎分享,转载请保留出处. Hello,小伙伴们,今天不聊技术,分享点有意思的东西.前段时间,表弟给我发过来一篇老外写的文章,以略带讽刺的对话方式调侃了自己对框架的看法,我 ...

  6. Shell脚本字符串截取方法总结

    Shell脚本8种字符串截取方法总结转自:https://www.cnblogs.com/ralphdc/p/8032335.html Linux 的字符串截取很有用.有八种方法.假设有变量 var= ...

  7. cordova配置与开发

    1.环境配置 1.1.安装ant 从 apache官网 下载ant,安装并配置,将ant.bat所在目录加到path环境变量,如c:\apache-ant\bin\.在cmd中运行以下语句如不报错即可 ...

  8. springboot热部署与监控

    一.热部署 添加依赖+Ctrl+F9 <dependency> <groupId>org.springframework.boot</groupId> <ar ...

  9. Linux:cut命令...未完待续

    一.定义 正如其名,cut的工作就是"剪",具体的说就是在文件中负责剪切数据用的.cut是以每一行为一个处理对象的,这种机制和sed是一样的. 2.剪切依据 cut命令主要是接受三 ...

  10. List如何一边遍历,一边删除?

    1.新手常犯的错误 可能很多新手(包括当年的我,哈哈)第一时间想到的写法是下面这样的: public static void main(String[] args) { List<String& ...