3 ms·
> it's not rocket science to handle it in a sane fashion even in a multi-threaded application It's not, though you need to be careful if you want to exit clean
by cryptonector 4y ago
> it's not rocket science to handle it in a sane fashion even in a multi-threaded application
It's not, though you need to be careful if you want to exit cleanly -- you can't just exit() or _exit(). You have to get all the threads to exit, and that requires a global volatile sig_atomic_t flag and some way to signal all threads that might be sleeping in event loops or what have you.
- deleted 4y ago[deleted]
- FeepingCreature 4y agoSure you can just exit(), you just have to be sure that all your on-disk state changes are atomic. Which you should make sure of anyways.
- quietbritishjim 4y agoA separate thread with sigwait() may be easier. Though I must admit, I've rarely had to do that manually, as I'm usually using a language or framework that gives an easier way to get notified about signals (e.g. Python KeyboardInterrupt or listeners in Boost ASIO or libuv). Aside from saving some boilerplate, those also emulate equivalent signals in Windows. Threads waiting on event loops is exactly what you want on shutdown: that's what you use to notify them to exit.
- cryptonector 4y agoI never use sigwait() or sigsuspend() -- I just have signal handlers that write a byte (e.g., the signal number) into a pipe, and maybe they set a global volatile sig_atomic_t variable. DJB calls this a "self-pipe". A self-pipe turns signals into I/O events that select/poll/epoll/event ports/kqueue/io_ring/whatever can handle like any other events. At exit time I just make sure every thread can get an event. The main thread can pthread_cond_wait() for all the other threads to exit, waiting for the count of them to fall to zero.
- quietbritishjim 4y agoAh self pipe is a good idea, I suspect that's what those async frameworks are doing under the hood.