5 ms·
The main reason is so that the type system knows which thread is which and can handle it differently. They may still inherit from the same implementation and d
by throwaway912598 6y ago
The main reason is so that the type system knows which thread is which and can handle it differently.
They may still inherit from the same implementation and do what you suggest though.
- dataflow 6y ago> The main reason is so that the type system knows which thread is which and can handle it differently. Why is this useful in this case, is my question. You can try to put lots of things into the type system that aren't, but that doesn't automatically make them better. In fact I'd argue it makes things worse here, e.g., now every container will be instantiated twice depending on whether you use jthreads or threads, almost doubling the amount of work the compiler has to do for them.
- throwaway912598 6y agoIt's useful because you may be able to make compile-time decisions on the basis of the type of thread you're dealing with. What those are, I don't know. As for instantiations, an astute library developer will be able to do the right thing. It's not that hard.
- gpderetta 6y agosay you have function that returns a thread object (which is perfectly fine as std::thread is moveable). The caller cannot assume that the thread will join on destruction and needs to conservatively join or detach explicitly anyway. Re container, they will only be instantiated twice if you actually use both std::jthread and std::thread of course. The idea (which I disagree) is that jthread is the better solution and std::thread is sort of deprecated.
- dataflow 6y ago> The caller cannot assume that the thread will join on destruction and needs to conservatively join or detach explicitly anyway. This seems a little backwards to me? If the thread should join on destruction then that flag should be set. If not then it should be clear. I'd argue that flag should probably be set in general (and it seems you might feel the same way), but if you have a reason to clear it, then you're just fighting your own program by ignoring it. > Re container, they will only be instantiated twice if you actually use both std::jthread and std::thread of course. The idea (which I disagree) is that jthread is the better solution and std::thread is sort of deprecated. Good point!
- gpderetta 6y agothe function that will be affected by the thread blocking might not be the one that has created the thread so it might not have a chance to set the flag. Of course you can handle it by declaring and documenting preconditions and so on, but, when possible, enforcing these sort of things at the type level is better.
- masklinn 6y ago> The main reason is so that the type system knows which thread is which and can handle it differently. Except that's not really the case: std::thread is joinable as well. The difference between the two is what happens in the dtor, respectively "terminate" and "join".
- throwaway912598 6y agoYes except when given a std::thread you don't know whether it will join in the destructor whereas with jthread you do. I personally don't know how it helps. But I'm sure the proposals had some reasoning.
- masklinn 6y ago> I personally don't know how it helps I really don't think it does personally. You can argue one way or the other with respect to safety (and I would very much agree that terminating on drop is insane), but that's really your backstop, and it's not really relevant to the person who is given a thread: they should know what they want to do with it, and if they want to join it they ought do so.
- dataflow 6y ago> it's not really relevant to the person who is given a thread: they should know what they want to do with it, and if they want to join it they ought do so. You might be onto something with this but it's not obvious to me. I would've thought if the caller says "don't join this on destruction", that means "I know what this thread does better than you because I created it, and you cannot expect to be able to wait for it to exit in the general case" (e.g., maybe it infinite-loops or something). Under what scenario would the callee have a good reason to give you a non-auto-joining thread, and you (the caller) a good reason to override that assessment on destruction by default, and why are these scenarios the desired general behavior? (I can understand special cases, like when you pass a particular message to the thread to get it to quit, but not the general case for destructors.)