std::thread中.detach()和.join()

1 .detach() 和 .join():

.detach() 是 C++ 标准库中的 std::thread 类的一个成员函数。调用 .detach() 会使当前线程独立运行,从而使得该线程在后台运行,而不阻塞主线程或其他线程的执行。具体来说,.detach() 的作用是将线程从其所属的 std::thread 对象中分离出来,这样 std::thread 对象就不再管理这个线程的生命周期了。

以下是 .detach() 的详细解释:

线程分离与管理

当你创建一个线程时,例如:

std::thread t(handle_connection, ctx, mb_mapping);

如果不调用 t.join()t.detach(),程序会在 t 析构时终止,抛出一个异常。

t.join() 和 t.detach() 的区别

t.join() 会阻塞当前线程,直到线程 t 完成执行。这通常用于确保线程在程序结束之前已经完成。例如:

t.join();

t.detach() 会使线程 t 在后台独立运行,不再与 std::thread 对象关联。这意味着一旦调用了 t.detach(),你就无法再通过 t 管理或等待这个线程的完成。例如:

t.detach();

使用 t.detach() 的情形

在你的代码中,使用 .detach() 的目的是允许每个客户端连接在独立的线程中处理,而不阻塞主线程接收新连接。以下是你代码中的示例:

while (true)
{
    modbus_t *ctx = modbus_new_tcp("127.0.0.1", 1502);
    int client_socket = modbus_tcp_accept(ctx, &socket);
    if (client_socket == -1)
    {
        modbus_free(ctx);
        continue;
    }
    std::thread(handle_connection, ctx, mb_mapping).detach();
}

在这里,每次有新的客户端连接时,都会创建一个新的线程来处理该连接。通过调用 .detach(),新线程会在后台运行,允许主线程继续接受新的客户端连接,而不会被阻塞。

注意事项
使用 t.detach() 时需要注意以下几点:

资源管理:分离的线程需要自己管理资源,因为主线程不会等待它的完成。
生命周期管理:需要确保分离的线程在使用的资源(如 ctxmb_mapping)有效期间内完成,否则可能会导致未定义行为。
调试难度:分离的线程在调试和错误处理上会更加复杂,因为它们在后台独立运行,不易控制。
总之,.detach() 在处理并发连接时非常有用,但需要小心管理资源和线程生命周期,以避免潜在的竞争条件和资源泄漏。

2 不写 .detach() 和 .join():

如果你只这样写:

std::thread(handle_connection, ctx, mb_mapping);

而不调用 .detach().join(),当离开循环或者当前作用域时,std::thread 对象会被销毁,导致程序崩溃。原因如下:

线程对象的生命周期管理

  1. std::thread 对象销毁时的行为:
    如果 std::thread 对象被销毁时,线程还在运行而你没有调用 .detach().join(),程序会调用 std::terminate(),导致程序异常终止。
  2. 未调用 .detach().join() 的问题:
    当你只创建线程但不调用 .detach().join(),线程对象会尝试在其析构函数中管理线程的生命周期,而未处理的线程会触发 std::terminate()

正确的线程管理方法

要正确管理线程,你需要确保在离开作用域前,调用 .detach().join()。如下所示:

使用 .detach():
将线程分离,使其独立运行:

std::thread(handle_connection, ctx, mb_mapping).detach();

使用 .join():
等待线程完成执行:

std::thread t(handle_connection, ctx, mb_mapping);
t.join();

总结

std::thread 创建后,如果离开作用域之前未调用 .detach().join(),程序会崩溃。使用 .detach() 允许线程在后台独立运行,而使用 .join() 则等待线程完成执行。你的示例中,.detach() 使线程独立运行,允许主线程继续处理新的连接。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值