[HACKERS] fork()-safety, thread-safety - Mailing list pgsql-hackers
From | Nico Williams |
---|---|
Subject | [HACKERS] fork()-safety, thread-safety |
Date | |
Msg-id | 20171005220221.GZ1251@localhost Whole thread Raw |
Responses |
Re: [HACKERS] fork()-safety, thread-safety
|
List | pgsql-hackers |
A thread on parallelization made me wonder so I took a look: - src/bin/*/parallel.c uses threads on WIN32- src/bin/*/parallel.c uses fork() on not-WIN32 (Ditto src/bin/pg_basebackup/pg_basebackup.c and src/backend/postmaster/syslogger.c.) A quick look at the functions called on the child side of fork() makes me think that it's unlikely that the children hereuse async-signal-safe functions only. Why not use threads on all systems where threads are available when we'd use threads on some such systems? If this codeis thread-safe on WIN32, why wouldn't it be thread-safe on POSIX? (Well, naturally there may be calls to, e.g., getpwnam()and such that would not be thread-safe on POSIX, and which might not exist on WIN32. But I mean, aside fromthat, if synchronization is done correctly on WIN32, what would stop that from being true on POSIX?) - fork() is used in a number of places where execl() or execv() are called immediately after (and exit() if the exec fails). It would be better to use vfork() where available and _exit() instead of exit(). Alternatively posix_spawn() should be used (which generally uses vfork() or equivalent under the covers). vfork() is widely demonized, but it's actually quite superior (performance-wise) to fork() when all you want to do isexec-or-exit since no page copying (COW or otherwise) needs be done when using vfork(). It's actually safer to use vfork() because POSIX limits one to async-signal-safe functions between fork() and exec-or-exit... With fork(), where neither the parent nor the child immediately execs-or- exits, it's too easy to failto make sure that the code they execute is fork-safe. Whereas with vfork() the fact that the parent (just the onethread, incidentally, not all of them[*]) blocks until the child execs-or-exits means it's impossible to fail to noticea long-running child that does lots of fork-unsafe work. It's safer still to use posix_spawn(), naturally. In Unix-land it's standard practice to ignore the async-signal-safe requirement when using fork() early on in a daemon's life to start worker processes. This is fine, of course, though if we're using CreateProcess*()/_spawn() on WIN32 anyways, it might be best to do the equivalent on Unix and just spawn the children -- if nothing else, this would reduce the likelihood of unintended divergence between WIN32 and Unix. Nico [*] Actually, I do believe that on Solaris/Illumos vfork() stops all threads in the parent, if I remember correctly anyways. Linux's and NetBSD's vfork() only stops the one thread in the parent that called it. I haven't checked otherBSDs. There was a patch for NetBSD to stop all threads in the parent, but I convinced the NetBSD community to discardthat patch. -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
pgsql-hackers by date: