◐ Shell
clean mode source ↗

Message 162036 - Python tracker

> I think forkall() on Solaris acts like that, but the normal fork() 
> function does not.  Only the thread which performs fork() will survive 
> in the child process.

Sorry, brain fail. A slightly more contrived failure case is this:

subprocess.Popen(
  ..., 
  preexec_fn=lambda: conn.doWork()
)

Everything else is the same.

Another failure case is:

  class MySQLConn:
    ... doWork as before ...

    def __del__(self):
      self.doWork()

Followed by:

  def thread3(conn):
    while True:
      subprocess.call(['nonexistent_program']) 
      time.sleep(0.1)

The destructor will fire in the child and corrupt the parent's data.

An analogous example is:

  conn = MySQLConn()
  start_thread1(conn)
  start_thread2(conn):
  while True:
    if os.fork() == 0:  # child
      raise Exception('doom')  # triggers destructor

Basically, it is really really dangerous to release locks that protect any resources that are not copied by fork (i.e. network resources, files, DB connections, etc, etc).