The C based gRPC (C++, Python, Ruby, Objective-C, PHP, C#) https://grpc.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

75 lines
2.4 KiB

6 years ago
## Multiprocessing with gRPC Python
Multiprocessing allows application developers to sidestep the Python global
interpreter lock and achieve true parallelism on multicore systems.
6 years ago
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), 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.
6 years ago
5 years ago
Calling `fork` without `exec` in your process *is* supported
before any gRPC servers have been instantiated. Application developers can
6 years ago
take advantage of this to parallelize their CPU-intensive operations.
## Calculating Prime Numbers with Multiple Processes
6 years ago
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.
```python
_PROCESS_COUNT = multiprocessing.cpu_count()
```
On the server side, we detect the number of CPUs available on the system and
spawn exactly that many child processes. If we spin up fewer, we won't be taking
full advantage of the hardware resources available.
## Running the Example
6 years ago
To run the server,
[ensure `bazel` is installed](https://docs.bazel.build/versions/master/install.html)
and run:
```
bazel run //examples/python/multiprocessing:server &
```
Note the address at which the server is running. For example,
```
...
[PID 107153] Binding to '[::]:33915'
[PID 107507] Starting new server.
[PID 107508] Starting new server.
...
```
Note that several servers have been started, each with its own PID.
6 years ago
Now, start the client by running
```
bazel run //examples/python/multiprocessing:client -- [SERVER_ADDRESS]
```
For example,
```
bazel run //examples/python/multiprocessing:client -- [::]:33915
```
Alternatively, generate code using the following and then run the client and server
directly:
```python
cd examples/python/helloworld
python -m grpc_tools.protoc -I . prime.proto --python_out=. --grpc_python_out=.
```