【问题标题】:ZeroMQ: How to handle Ctrl-C on WindowsZeroMQ:如何在 Windows 上处理 Ctrl-C
【发布时间】:2014-02-28 00:50:26
【问题描述】:

我想知道如何处理从 Windows 控制台发出的Ctrl-C

#include <iostream>
#include <zmq.hpp>
#include <windows.h>

BOOL WINAPI consoleHandler( DWORD dwCtrlType ) {
    // what to do here?
    return TRUE;
}

int main() {
    SetConsoleCtrlHandler( consoleHandler, TRUE );

    zmq::context_t context( 1 );
    zmq::socket_t socket( context, ZMQ_REP );
    socket.bind( "tcp://*:5555" );

    while ( true ) {
        zmq::message_t request;
        try {
            socket.recv( &request );
        }
        catch(zmq::error_t& e) {
            std::cout << "zmq error" << std::endl;
        }
    }
}

这会安装一个处理函数,该函数可以作用于来自控制台的CTRL_C_EVENT。目前,它什么也不做。因此,revc 调用不会失败并抛出异常 as described here (in "Error handling")

我想做的是break在异常处理程序中执行循环,并让 C++ 绑定的 RAII 功能在退出main() 时进行所需的清理。

【问题讨论】:

    标签: c++ windows winapi zeromq


    【解决方案1】:

    通常我会创建一个标志或某种类型 - 全局布尔或内核事件。

    然后你循环等待这个标志被重置 - 所以在你的情况下,我会创建一个简单的全局 bool 然后循环它而不是 while (true)。

    所以:

    bool g_shutdown = false;
    
    BOOL WINAPI consoleHandler( DWORD dwCtrlType ) {
        g_shutdown = true;
        return TRUE;
    }
    
    while (!g_shutdown)
    {
    // do your zmq work
    }
    

    它简单但有效——虽然这不会杀死你的程序,直到 zmq 工作再次进入 while 循环检查。 (您通常可以通过关闭套接字变量来做到这一点)

    为了更健壮(即更快地杀死,取决于您的情况)使用事件和 WaitforMultipleObject 调用来等待此关闭事件和您的程序正在等待的任何其他事件(即该套接字的 recv 调用)。

    【讨论】:

    • 是的,zguide example 就是这样做的。也许我被“阻止读取会发出信号”评论误导了。还有一个问题:万一没有消息到达我的套接字,我必须添加超时吗?
    • 如果您在循环中阻塞,添加超时总是一个好主意。然后你至少可以定期检查你的循环控制(如果你喜欢那种东西,可以选择在日志中写一个“仍在工作”的消息)。
    猜你喜欢
    • 1970-01-01
    • 2013-08-19
    • 1970-01-01
    • 2011-11-16
    • 2012-03-20
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 2018-03-21
    相关资源
    最近更新 更多