最近公司做项目,需要实现一个单机多进程通信程序(进程数不超过30)
项目基于Fedora20、gcc4.8、cmake3.15
基于之前公司之前的架构,我的想法是提供一个虚基类,伪代码如:
class Base {
public:
using callback = void (Base::*)(jsonobj)
Base(string name) : m_strName(name) {
InitBusiness();
}
virtual ~Base() {}
// 调用之后就一直处理同异步消息
// block:是否阻塞调用
bool start(bool block = true);
/*
同步调用
name: 进程名(应唯一)
function: 方法名
param: 参数(json对象)
result: 调用结果(json对象)
timeout: 调用超时返回
*/
int SyncCall(string name, string function, jsonobj param, jsonobj& result, int timeout = 10);
/*
异步调用
name: 进程名(应唯一)
function: 方法名
param: 参数(json对象)
result: 调用结果(json对象)
timeout: 调用超时返回
*/
int AsyncCall(string name, string function, jsonobj param, callback cb);
/*
进程初始化,初始化进程自己的业务
*/
protected:
virtual int InitBusiness() = 0;
private:
const std::string m_strName;
UnixDomainSocketWrapper* m_pCommunicator;
// ......
};
然后所有进程业务类都需要继承这个基类,以获得和其他进程进行同步异步通信的接口,业务类进程如:
//进程一
class CTest1 : public Base {
public:
CTest1(string name) : Base(name) {}
virtual ~CTest1() {}
// 对外接口
int Test1(jsonobj, jsonobj&);
protected:
virtual int InitBusiness() {
// 初始化业务
Business1();
Business2();
std::thread(&CTest1::CycleBusiness, this).detach();
}
private:
// 回调
void OnTest2CB(jsonobj param);
// 业务
void Business1() {
jsonobj param, result;
SyncCall("CTest2", "Test2", param, result);
AsyncCall("CTest2", "Test2", param, OnTest2CB);
}
void Business2();
void CycleBusiness();
};
int main() {
Base* obj = new CTest1("CTest1");
obj->start();
delete obj;
return 0;
}
//进程二
class CTest2 : public Base {
public:
CTest2(string name) : Base(name) {}
virtual ~CTest2() {}
// 对外接口
int Test2(jsonobj, jsonobj&);
protected:
virtual int InitBusiness() {
// 初始化业务
Business1();
Business2();
std::thread(&CTest2::CycleBusiness, this).detach();
}
private:
// 回调
void OnTest1CB(jsonobj param);
void Business1() {
jsonobj param, result;
SyncCall("CTest1", "Test1", param, result);
AsyncCall("CTest1", "Test1", param, OnTest1CB);
}
void Business2();
void CycleBusiness();
};
int main() {
Base* obj = new CTest2("CTest2");
obj->start();
delete obj;
return 0;
}
以上为伪代码只做示例用,在此记录一下
项目通信的底层是采用的unix本地套接字,目前正考虑使用zeromq作为替代.
zeromq以嵌入式网络编程库的形式实现了一个并行开发框架(concurrency framework),
能够提供进程内(inproc)、进程间(IPC)、网络(TCP)和广播方式的消息信道,
并支持扇出(fan-out)、发布-订阅(pub-sub)、任务分发(task distribution)、请求/响应(request-reply)等通信模式。
ZeroMQ的性能足以用来构建集群产品,
其异步I/O模型能够为多核消息系统提供足够的扩展性。
ZeroMQ支持30多种语言的API,可以用于绝大多数操作系统。
在提供这些优秀特性的同时,ZeroMQ是开源的,遵循LGPLv3许可。
ZeroMQ的明确目标是“成为标准网络协议栈的一部分,之后进入Linux内核”。
不知道为什么在windows上用edge浏览器点击发布文章,出不来editor,我就纳了闷了。。。