xref: /aosp_15_r20/external/grpc-grpc/doc/fork_support.md (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1# Background
2
3In Python, multithreading is ineffective at concurrency for CPU bound tasks due
4to the GIL (global interpreter lock).  Extension modules can release the GIL in
5CPU bound tasks, but that isn't an option in pure Python. Users use libraries
6such as multiprocessing, subprocess, concurrent.futures.ProcessPoolExecutor,
7etc, to work around the GIL. These modules call `fork()` underneath the hood.
8Various issues have been reported when using these modules with gRPC Python.
9gRPC Python wraps gRPC core, which uses multithreading for performance, and
10hence doesn't support `fork()`. Historically, we didn't support forking in gRPC,
11but some users seemed to be doing fine until their code started to break on
12version 1.6.  This was likely caused by the addition of background c-threads and
13a background Python thread.
14
15# Current Status
16
17gRPC Python applications can enable client-side forking when two environment
18variables are given:
19
20```
21export GRPC_ENABLE_FORK_SUPPORT=true
22export GRPC_POLL_STRATEGY=poll
23```
24
25The fork-support effort only works with "epoll1" and "poll" polling strategy.
26There is no active development to extend fork-support's coverage.
27
28For more details about poll strategy setting, see
29https://github.com/grpc/grpc/blob/master/doc/environment_variables.md.
30
31# Alternative: use after fork
32
33Complexities mentioned in the background section are inevitable for "pre-fork"
34usage, where the application creates gRPC Python objects (e.g., client channel)
35before invoking `fork()`. However, if the application only instantiate gRPC
36Python objects after calling `fork()`, then `fork()` will work normally, since
37there is no C extension binding at this point. This idea is demonstrated by the
38[multiprocessing
39example](https://github.com/grpc/grpc/tree/master/examples/python/multiprocessing).
40