I have a program that uses multiple threads to brute force the decryption of some encrypted string. The main thread has a channel, and the sender is cloned and sent to each thread. When a thread finds an answer, it sends it to the receiver which is in the main thread.
In this program I am not joining the threads, instead I use the blocking call sender.recv()
to suspend the main thread until a single other thread finishes.
My hope is, once this call finishes, the main thread will return and all the other worker threads will be terminated.
Is this a poor design choice? Are there drawbacks of not having some condition in the other threads which would cause them to return when the solution has been discovered? Is it okay/safe to rely on the compiler to clean up my threads before they've technically finished?
CodePudding user response:
Assuming there's no cleanup to be done, what you've done is mostly harmless. I'm assuming your worker thread looks something like this right now.
fn my_thread() {
// ... lots of hard work ...
channel.send(my_result);
}
and if that's the case, then "I received the result" and "the other thread is terminated" are very similar events, and the difference of "this function returned" is probably irrelevant. But suppose someone comes along and changes the code to look like this.
fn my_thread() {
// ... lots of hard work ...
channel.send(my_result);
do_cleanup_stuff();
}
Now do_cleanup_stuff()
might not get a chance to run, if your main thread terminates before my_thread
does. If that cleanup function is important, that could cause problems. And it could be more subtle than that. If any local variable in my_thread
holds a file handle or an open TCP stream or any other object with a nontrivial Drop
implementation, that value may not get a chance to Drop
properly if you don't join
the thread.
So it's probably best practice to join
everything, even if it's just a final step at the end of your main
.