Skip to content

Commit 594bece

Browse files
committed
11.7小节完成
1 parent d74bcf6 commit 594bece

File tree

1 file changed

+70
-73
lines changed

1 file changed

+70
-73
lines changed

source/c11/p07_communicate_simply_between_interpreters.rst

Lines changed: 70 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -5,91 +5,88 @@
55
----------
66
问题
77
----------
8-
You are running multiple instances of the Python interpreter, possibly on different ma‐
9-
chines, and you would like to exchange data between interpreters using messages.
8+
你在不同的机器上面运行着多个Python解释器实例,并希望能够在这些解释器之间通过消息来交换数据。
109

1110
|
1211
1312
----------
1413
解决方案
1514
----------
16-
It is easy to communicate between interpreters if you use the multiprocessing.con
17-
nection module. Here is a simple example of writing an echo server:
15+
通过使用 ``multiprocessing.connection`` 模块可以很容易的实现解释器之间的通信。
16+
下面是一个简单的应答服务器例子:
1817

19-
from multiprocessing.connection import Listener
20-
import traceback
18+
.. code-block:: python
2119
22-
def echo_client(conn):
23-
try:
24-
while True:
25-
msg = conn.recv()
26-
conn.send(msg)
27-
except EOFError:
28-
print('Connection closed')
29-
30-
def echo_server(address, authkey):
31-
serv = Listener(address, authkey=authkey)
32-
while True:
20+
from multiprocessing.connection import Listener
21+
import traceback
22+
23+
def echo_client(conn):
3324
try:
34-
client = serv.accept()
35-
36-
echo_client(client)
37-
except Exception:
38-
traceback.print_exc()
39-
40-
echo_server(('', 25000), authkey=b'peekaboo')
41-
42-
Here is a simple example of a client connecting to the server and sending various
43-
messages:
44-
45-
>>> from multiprocessing.connection import Client
46-
>>> c = Client(('localhost', 25000), authkey=b'peekaboo')
47-
>>> c.send('hello')
48-
>>> c.recv()
49-
'hello'
50-
>>> c.send(42)
51-
>>> c.recv()
52-
42
53-
>>> c.send([1, 2, 3, 4, 5])
54-
>>> c.recv()
55-
[1, 2, 3, 4, 5]
56-
>>>
57-
58-
Unlike a low-level socket, messages are kept intact (each object sent using send() is
59-
received in its entirety with recv()). In addition, objects are serialized using pickle.
60-
So, any object compatible with pickle can be sent or received over the connection.
25+
while True:
26+
msg = conn.recv()
27+
conn.send(msg)
28+
except EOFError:
29+
print('Connection closed')
30+
31+
def echo_server(address, authkey):
32+
serv = Listener(address, authkey=authkey)
33+
while True:
34+
try:
35+
client = serv.accept()
36+
37+
echo_client(client)
38+
except Exception:
39+
traceback.print_exc()
40+
41+
echo_server(('', 25000), authkey=b'peekaboo')
42+
43+
然后客户端连接服务器并发送消息的简单示例:
44+
45+
.. code-block:: python
46+
47+
>>> from multiprocessing.connection import Client
48+
>>> c = Client(('localhost', 25000), authkey=b'peekaboo')
49+
>>> c.send('hello')
50+
>>> c.recv()
51+
'hello'
52+
>>> c.send(42)
53+
>>> c.recv()
54+
42
55+
>>> c.send([1, 2, 3, 4, 5])
56+
>>> c.recv()
57+
[1, 2, 3, 4, 5]
58+
>>>
59+
60+
跟底层socket不同的是,每个消息会完整保存(每一个通过send()发送的对象能通过recv()来完整接受)。
61+
另外,所有对象会通过pickle序列化。因此,任何兼容pickle的对象都能在此连接上面被发送和接受。
6162

6263
|
6364
6465
----------
6566
讨论
6667
----------
67-
There are many packages and libraries related to implementing various forms of mes‐
68-
sage passing, such as ZeroMQ, Celery, and so forth. As an alternative, you might also
69-
be inclined to implement a message layer on top of low-level sockets. However, some‐
70-
times you just want a simple solution. The multiprocessing.connection library is just
71-
that—using a few simple primitives, you can easily connect interpreters together and
72-
have them exchange messages.
73-
If you know that the interpreters are going to be running on the same machine, you can
74-
use alternative forms of networking, such as UNIX domain sockets or Windows named
75-
pipes. To create a connection using a UNIX domain socket, simply change the address
76-
to a filename such as this:
77-
78-
s = Listener('/tmp/myconn', authkey=b'peekaboo')
79-
80-
To create a connection using a Windows named pipe, use a filename such as this:
81-
82-
s = Listener(r'\\.\pipe\myconn', authkey=b'peekaboo')
83-
84-
As a general rule, you would not be using multiprocessing to implement public-facing
85-
services. The authkey parameter to Client() and Listener() is there to help authen‐
86-
ticate the end points of the connection. Connection attempts with a bad key raise an
87-
exception. In addition, the module is probably best suited for long-running connections
88-
89-
(not a large number of short connections). For example, two interpreters might establish
90-
a connection at startup and keep the connection active for the entire duration of a
91-
problem.
92-
Don’t use multiprocessing if you need more low-level control over aspects of the con‐
93-
nection. For example, if you needed to support timeouts, nonblocking I/O, or anything
94-
similar, you’re probably better off using a different library or implementing such features
95-
on top of sockets instead.
68+
目前有很多用来实现各种消息传输的包和函数库,比如ZeroMQ、Celery等。
69+
你还有另外一种选择就是自己在底层socket基础之上来实现一个消息传输层。
70+
但是你想要简单一点的方案,那么这时候 ``multiprocessing.connection`` 就派上用场了。
71+
仅仅使用一些简单的语句即可实现多个解释器之间的消息通信。
72+
73+
如果你的解释器运行在同一台机器上面,那么你可以使用另外的通信机制,比如Unix域套接字或者是Windows命名管道。
74+
要想使用UNIX域套接字来创建一个连接,只需简单的将地址改写一个文件名即可:
75+
76+
.. code-block:: python
77+
78+
s = Listener('/tmp/myconn', authkey=b'peekaboo')
79+
80+
要想使用Windows命名管道来创建连接,只需像下面这样使用一个文件名:
81+
82+
.. code-block:: python
83+
84+
s = Listener(r'\\.\pipe\myconn', authkey=b'peekaboo')
85+
86+
一个通用准则是,你不要使用 ``multiprocessing`` 来实现一个对外的公共服务。
87+
``Client()`` 和 ``Listener()`` 中的 ``authkey`` 参数用来认证发起连接的终端用户。
88+
如果密钥不对会产生一个异常。此外,该模块最适合用来建立长连接(而不是大量的短连接),
89+
例如,两个解释器之间启动后就开始建立连接并在处理某个问题过程中会一直保持连接状态。
90+
91+
如果你需要对底层连接做更多的控制,比如需要支持超时、非阻塞I/O或其他类似的特性,
92+
你最好使用另外的库或者是在高层socket上来实现这些特性。

0 commit comments

Comments
 (0)