选择不在 Rust 中加入线程有什么缺点吗?
Are there any downsides to choosing not to join threads in Rust?
我有一个程序使用多线程暴力破解一些加密字符串。主线程有一个channel,sender被克隆并发送给各个线程。当线程找到答案时,它会将其发送到主线程中的接收器。
在这个程序中,我没有加入线程,而是使用阻塞调用 sender.recv()
挂起主线程,直到另一个线程完成。
我希望,一旦此调用完成,主线程将 return 而所有其他工作线程将终止。
这是一个糟糕的设计选择吗?当发现解决方案时,其他线程中没有某些条件会导致它们 return 是否存在缺点?是否 okay/safe 依靠编译器在技术上完成之前清理我的线程?
假设没有清理工作要做,那么你所做的基本上是无害的。我假设您的工作线程现在看起来像这样。
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();
}
现在 do_cleanup_stuff()
可能没有机会 运行,如果您的主线程在 my_thread
之前终止。如果清理功能很重要,那可能会导致问题。它可能比这更微妙。如果 my_thread
中的任何局部变量包含文件句柄或打开的 TCP 流或具有非平凡 Drop
实现的任何其他对象,如果您不这样做,该值可能无法正确 Drop
't join
线程。
所以最好的做法是 join
一切,即使这只是 main
.
结束时的最后一步
我有一个程序使用多线程暴力破解一些加密字符串。主线程有一个channel,sender被克隆并发送给各个线程。当线程找到答案时,它会将其发送到主线程中的接收器。
在这个程序中,我没有加入线程,而是使用阻塞调用 sender.recv()
挂起主线程,直到另一个线程完成。
我希望,一旦此调用完成,主线程将 return 而所有其他工作线程将终止。
这是一个糟糕的设计选择吗?当发现解决方案时,其他线程中没有某些条件会导致它们 return 是否存在缺点?是否 okay/safe 依靠编译器在技术上完成之前清理我的线程?
假设没有清理工作要做,那么你所做的基本上是无害的。我假设您的工作线程现在看起来像这样。
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();
}
现在 do_cleanup_stuff()
可能没有机会 运行,如果您的主线程在 my_thread
之前终止。如果清理功能很重要,那可能会导致问题。它可能比这更微妙。如果 my_thread
中的任何局部变量包含文件句柄或打开的 TCP 流或具有非平凡 Drop
实现的任何其他对象,如果您不这样做,该值可能无法正确 Drop
't join
线程。
所以最好的做法是 join
一切,即使这只是 main
.