libgo & zeromq —— C++下的协程与消息队列的配合

libgo通过hook了网络阻塞函数来实现协程的调度,但是zeromq只需要原生的函数,如果hook则会报错,Assertion failed: pfd.revents & POLLIN (src/signaler.cpp:261),这时候我们只想要libgo的线程调度功能怎么办?libgo & zeromq —— C++下的协程与消息队列的配合_第1张图片

 只要重新编译一次libgo,把disable_hook打开就可以,如果使用hook版本的,则会出现libgo & zeromq —— C++下的协程与消息队列的配合_第2张图片这个问题。

于是我们重新编译

libgo & zeromq —— C++下的协程与消息队列的配合_第3张图片

编译完成后,重新编译一次server & client 即可完成。

服务端

/*
    ZMQ订阅服务器

*/
#include
#include
#include

using namespace std;
int main(){
    int port;
    cout<<"请输入你想发布订阅的端口:";
    cin>>port;
    stringstream os;
    os<<"tcp://*:"<>";
        cin>>buffer;
        zmq_send(publisher,buffer,sizeof(buffer),0);
    }
    return 0;
}

客户端 

/*
    ZQM+libgo订阅客户端,可以协程实现对多个服务器的订阅
*/
#include
#include
#include
#include

using namespace std;

int main(){
    stringstream os;
    go [&os](){
        int port;
        while(1){
            cout<<"请输入要订阅的服务器端口:";
            cin>>port;
            os.str("");
            os<<"tcp://127.0.0.1:"<

最后效果大概是这样

libgo & zeromq —— C++下的协程与消息队列的配合_第4张图片

但是这样使用协程强行设置非阻塞和co_sleep的话,CPU其实占用还是很高 libgo & zeromq —— C++下的协程与消息队列的配合_第5张图片

如果在 zmq_recv设置为阻塞,那么阻塞的协程反而会卡住线程,到最后libgo就会自己开一个新的线程去调度协程,那为何不直接用线程做呢? 

所以不是很推荐这样的做法,如果开线程,在线程里面阻塞,或者使用zeromq自带的 Divide and Conquer 模式,可以降低CPU占用,因为zeromq实际上和libgo所hook的网络函数有冲突。

那么 libgo在哪些地方有用呢?我个人感觉是:自己手写网络应用程序的时候,因为只有这个时候才能保证没有错误,否则一些开源的网络库如果这样hook进去的话不保证会成功运行。

你可能感兴趣的:(C++,ZeroMQ,libgo)