Update documentation

pull/22643/head
Richard Belleville 5 years ago
parent 4e6327493d
commit 96024a9ad3
  1. 17
      examples/python/multiprocessing/README.md
  2. 6
      examples/python/multiprocessing/server.py

@ -1,16 +1,19 @@
## Multiprocessing with gRPC Python
Multiprocessing allows application developers to sidestep the Python global
interpreter lock and achieve true concurrency on multicore systems.
interpreter lock and achieve true parallelism on multicore systems.
Unfortunately, using multiprocessing and gRPC Python is not yet as simple as
instantiating your server with a `futures.ProcessPoolExecutor`.
The library is implemented as a C extension, maintaining much of the state that
drives the system in native code. As such, upon calling
[`fork`](http://man7.org/linux/man-pages/man2/fork.2.html), much of the
state copied into the child process is invalid, leading to hangs and crashes.
[`fork`](http://man7.org/linux/man-pages/man2/fork.2.html), any threads in a
critical section may leave the state of the gRPC library invalid in the child
process. See this [excellent research
paper](https://www.microsoft.com/en-us/research/uploads/prod/2019/04/fork-hotos19.pdf)
for a thorough discussion of the topic.
However, calling `fork` without `exec` in your python process is supported
Ccalling `fork` without `exec` in your process *is* supported
*before* any gRPC servers have been instantiated. Application developers can
take advantage of this to parallelize their CPU-intensive operations.
@ -18,11 +21,7 @@ take advantage of this to parallelize their CPU-intensive operations.
This example calculates the first 10,000 prime numbers as an RPC. We instantiate
one server per subprocess, balancing requests between the servers using the
[`SO_REUSEPORT`](https://lwn.net/Articles/542629/) socket option. Note that this
option is not available in `manylinux1` distributions, which are, as of the time
of writing, the only gRPC Python wheels available on PyPI. To take advantage of this
feature, you'll need to build from source, either using bazel (as we do for
these examples) or via pip, using `pip install grpcio --no-binary grpcio`.
[`SO_REUSEPORT`](https://lwn.net/Articles/542629/) socket option.
```python
_PROCESS_COUNT = multiprocessing.cpu_count()

@ -67,12 +67,6 @@ def _run_server(bind_address):
_LOGGER.info('Starting new server.')
options = (('grpc.so_reuseport', 1),)
# WARNING: This example takes advantage of SO_REUSEPORT. Due to the
# limitations of manylinux1, none of our precompiled Linux wheels currently
# support this option. (https://github.com/grpc/grpc/issues/18210). To take
# advantage of this feature, install from source with
# `pip install grpcio --no-binary grpcio`.
server = grpc.server(futures.ThreadPoolExecutor(
max_workers=_THREAD_CONCURRENCY,),
options=options)

Loading…
Cancel
Save