c++中的多线程服务器,如何很好地终止线程和清理

Multithread server in C++, how to terminate threads and clean up nicely

本文关键字:很好 终止 线程 多线程 服务器 何很好 c++      更新时间:2023-10-16

我用c++编写的服务器像代理一样工作。主要功能:

try
{
    Connector c(ip); //establishes persistent connection to the server B
    Listener1 l1(port); //listens incoming connection to the server A (our proxy) and push them into the queue
    Listener2 l2(&c); //listens responses (also push messages) from the server B and push them into the queue
    Proxy p(&c, &l1, &l2); //pulls clients  out from the queue and forwards requests to the server B, pull out everything from the listener2 queue and returns as a responce
    KeepAlive k(&l1, &p); //pushes the empty client to the listeners1's queue thus the proxy sends keepalive to the server B and the response is discarded
    l1.start();
    p.start();
    l2.start();
    k.start();
    l1.join();
    p.join();
    l2.join();
    k.join();
catch(std::string e)
{
    std::cerr << "Error: " << e << std::endl;
    return -1;
}

目前我有以下问题/疑问:

* * 1。**我抛出一个异常从构造函数,这是好的做法吗?当无法建立连接时抛出异常,我猜这就是为什么不应该创建对象的原因。

* * 2。**当连接超时或服务器B关闭连接等时,关闭应用程序安全和清理存在问题。listener1和listener2使用阻塞函数(系统调用accept()和来自openssl lib的BIO_read),因此不可能仅从另一个线程设置循环条件。问题还在于所有模块都是连接的,并且使用互斥锁共享资源。我当前的代码只是调用exit函数来终止整个应用程序。

我知道这不是一个完美的解决方案,我感谢任何建议和提示。

Thanks in advance

构造函数失败时应该抛出异常。c++就是为了很好地处理这个问题而设计的。当且仅当基类和成员已经构造时,它们才被清理。

阻塞来自其他库的函数总是一个问题。Windows和POSIX处理得很好:WSAWaitForMultipleObjectExselect允许你添加一个额外的句柄,你可以用它来解除等待阻塞。

accept调用中,您可以通过从主线程通过localhost创建连接来实现此操作。检测到这个"异常"连接将是停止接受进一步连接的信号。

至于openSSL的读取,我只会从主线程关闭套接字,线程安全是该死的。我会确保在关闭的很晚的时候这样做,并且我不期望库在那个时间点之后还能使用。

相关文章: