如何从另一个线程中断 websocket(使用 boost beast)?

Posted

技术标签:

【中文标题】如何从另一个线程中断 websocket(使用 boost beast)?【英文标题】:How interrupt a websocket (using boost beast) from another thread? 【发布时间】:2021-01-29 21:13:15 【问题描述】:

我正在使用 boost beast 1.74.0。在另一个线程中,我尝试关闭 websocket,但代码在“acceptor.accept(socket,endpoint)”处被破坏,并且在调用关闭后我收到“信号:SIG32(实时事件 32)”。

从代码部分监听连接,我需要更改什么才能正确中断接受服务?

...
 _acceptor = &acceptor;
 _keepAlive = true;
 while (_keepAlive) 
            tcp::socket socketioc;
            // Block until we get a connection
            acceptor.accept(socket, endpoint);

            // Launch the session, transferring ownership of the socket
            std::thread(
                    &WebSocketServer::doSession,
                    std::move(socket),
                    this,
                    this,
                    getHeaderServer()
            ).detach();
        

关闭另一个线程调用的函数

void WebSocketServer::close() 
    if (_acceptor != nullptr) this->close();
    _keepAlive = false;

【问题讨论】:

【参考方案1】:

glibc 使用 SIG32 表示取消使用 pthread 库创建的线程。您是否尝试使用pthread_kill

如果没有,您可能只是因为您在 GDB 下运行它而目睹了这一点。这应该可以通过告诉 GDB 忽略它来解决:

handle SIG32 nostop noprint

最后回到原来的问题:

Boost Thread 中有中断点。他们可以帮助您如果您可以切换到 Boost Thread boost::thread 而不是 std::thread。此外,您必须更改线程代码以实际检查中断:https://www.boost.org/doc/libs/1_75_0/doc/html/thread/thread_management.html#thread.thread_management.tutorial.interruption

既然听起来你实际上想终止接受循环,为什么不“简单地”取消接受器呢?我不完全确定这适用于同步操作,但您当然可以轻松地使用异步接受。

注意同步对接受器对象本身的访问。这意味着要么在同一个线程上运行cancel,要么在同一个线程上运行async_accept,或者从同一个strand。在这一点上,这听起来肯定更容易异步完成整个事情。

【讨论】:

以上是关于如何从另一个线程中断 websocket(使用 boost beast)?的主要内容,如果未能解决你的问题,请参考以下文章

Python Tornado 从另一个线程发送 WebSocket 消息

从另一个线程中断 event_base_dispatch

Gtkmm:如何从另一个线程更新 UI?连续不断

从另一个线程访问线程本地

从另一个线程更改视图[关闭]

即使网络中断,如何继续在 websockets 中发送消息?