@@ -14,21 +14,15 @@ for threaded applications.
1414Is PyMongo fork-safe?
1515---------------------
1616
17- Starting in PyMongo 4.3, forking on a compatible Python interpreter while
18- using a client will result in all locks held by :class: `~bson.objectid
19- .ObjectId ` and :class: `~pymongo.mongo_client.MongoClient ` being released in
20- the child, as well as state shared between child and parent processes being
21- reset.
22-
23- If greenlet has been imported (usually with a library like gevent or
24- Eventlet), care must be taken when using instances of :class: `~pymongo
25- .mongo_client.MongoClient ` with ``fork() ``. Specifically, instances of
26- MongoClient must not be copied from a parent process to a child process.
27- Instead, the parent process and each child process must create their own
28- instances of MongoClient. Instances of MongoClient copied from the parent
29- process have a high probability of deadlock in the child process due to the
30- inherent incompatibilities between ``fork() ``, threads, and locks described
31- :ref: `below<pymongo-fork-safe-details> `.
17+ PyMongo is not fork-safe. Care must be taken when using instances of
18+ :class: `~pymongo.mongo_client.MongoClient ` with ``fork() ``. Specifically,
19+ instances of MongoClient must not be copied from a parent process to
20+ a child process. Instead, the parent process and each child process must
21+ create their own instances of MongoClient. Instances of MongoClient copied from
22+ the parent process have a high probability of deadlock in the child process due
23+ to the inherent incompatibilities between ``fork() ``, threads, and locks
24+ described :ref: `below <pymongo-fork-safe-details >`. PyMongo will attempt to
25+ issue a warning if there is a chance of this deadlock occurring.
3226
3327.. _pymongo-fork-safe-details :
3428
@@ -44,10 +38,33 @@ created by ``fork()`` only has one thread, so any locks that were taken out by
4438other threads in the parent will never be released in the child. The next time
4539the child process attempts to acquire one of these locks, deadlock occurs.
4640
41+ Starting in version 4.3, PyMongo utilizes :py:func: `os.register_at_fork ` to
42+ reset its locks and other shared state in the child process after a
43+ :py:func: `os.fork ` to reduce the frequency of deadlocks. However deadlocks
44+ are still possible because libraries that PyMongo depends on, like `OpenSSL `_
45+ and `getaddrinfo(3) `_ (on some platforms), are not fork() safe in a
46+ multithreaded application. Linux also imposes the restriction that:
47+
48+ After a `fork() `_ in a multithreaded program, the child can
49+ safely call only async-signal-safe functions (see
50+ `signal-safety(7) `_) until such time as it calls `execve(2) `_.
51+
52+ PyMongo relies on functions that are *not * `async-signal-safe `_ and hence the
53+ child process can experience deadlocks or crashes when attempting to call
54+ a non `async-signal-safe `_ function. For examples of deadlocks or crashes
55+ that could occur see `PYTHON-3406 `_.
56+
4757For a long but interesting read about the problems of Python locks in
4858multithreaded contexts with ``fork() ``, see http://bugs.python.org/issue6721.
4959
5060.. _not fork-safe : http://bugs.python.org/issue6721
61+ .. _OpenSSL : https://github.com/openssl/openssl/issues/19066
62+ .. _fork() : https://man7.org/linux/man-pages/man2/fork.2.html
63+ .. _signal-safety(7) : https://man7.org/linux/man-pages/man7/signal-safety.7.html
64+ .. _async-signal-safe : https://man7.org/linux/man-pages/man7/signal-safety.7.html
65+ .. _execve(2) : https://man7.org/linux/man-pages/man2/execve.2.html
66+ .. _getaddrinfo(3) : https://man7.org/linux/man-pages/man3/gai_strerror.3.html
67+ .. _PYTHON-3406 : https://jira.mongodb.org/browse/PYTHON-3406
5168
5269.. _connection-pooling :
5370
0 commit comments