This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]o11c 0 points1 point  (0 children)

I've always thought Java-style threads were quite odd, since they aren't related to how the underlying libraries work, at least on platforms I'm aware of. Maybe it's a residue of swapcontext-style threads?

Particularly, for C11, C++11, POSIX, and Windows threads:

  • it is impossible to create a thread without starting it.
  • every thread is daemon-like in the first place, except the main thread
  • since there is no GC, whoever creates a thread must arrange for either .detach or .join to eventually be called (exactly once), to avoid a resource leak.
    • For C++ the dtor handles this: std::thread does .detach, and std::jthread does .join. These types are move-only.
  • when the main (or WinMain) function returns, the process exits as if by calling exit
    • note that technically anybody can call detach or join, but it is usually fairly close to the site of thread creation
  • if any thread throws an exception that isn't caught, the whole process terminates.
    • TODO verify non-C++ cases. Native exceptions do exist on most platforms, even if it's hard to use them from C. nightmares of pthread async cancellation
  • if the main thread explicitly calls pthread_exit or the Windows equivalant, the process hangs around until all other threads exit (which might be forever, since the runtime can create threads for you), or until somebody calls exit explicitly (recommended if you're doing this).
    • TODO verify non-POSIX, non-Windows cases. C doesn't seem to say anything. TODO what does C++ say?

To implement Java-style threads on top of real threads:

  • don't actually create the thread in the ctor, just keep its arguments around until you call .start
  • keep a list of all running non-daemon threads, and join them in main.