选择不加入 Rust 中的线程有什么缺点吗?



我有一个程序,它使用多个线程来暴力破解一些加密字符串。主线程有一个通道,发送方被克隆并发送到每个线程。当线程找到答案时,它会将其发送到主线程中的接收器。

在这个程序中,我没有加入线程,而是使用阻塞调用sender.recv()挂起主线程,直到另一个线程完成。

我希望,一旦此调用完成,主线程将返回,所有其他工作线程将终止。

这是一个糟糕的设计选择吗?是否存在在其他线程中没有某些条件的缺点,从而导致它们在发现解决方案时返回?在线程技术上完成之前依靠编译器来清理线程可以/安全吗?

假设没有清理要做,你所做的基本上是无害的。我假设您的工作线程现在看起来像这样。

fn my_thread() {
// ... lots of hard work ...
channel.send(my_result);
}

如果是这样的话,那么"我收到了结果"和"另一个线程被终止"是非常相似的事件,"这个函数返回"的区别可能无关紧要。但是假设有人出现并将代码更改为如下所示。

fn my_thread() {
// ... lots of hard work ...
channel.send(my_result);
do_cleanup_stuff();
}

现在,如果您的主线程在my_thread之前终止,do_cleanup_stuff()可能没有机会运行。如果该清理功能很重要,则可能会导致问题。它可能比这更微妙。如果my_thread中的任何局部变量包含文件句柄或打开的 TCP 流或任何其他具有非平凡Drop实现的对象,如果不join线程,则该值可能无法正确Drop

因此,最好的做法可能是join所有事情,即使这只是main结束时的最后一步。

最新更新