服务器:
import time
import random
from threading import Thread
from xmlrpc.server import SimpleXMLRPCServer
class ServerThread(Thread):
def __init__(self, server_addr):
┆ Thread.__init__(self)
┆ self.server = SimpleXMLRPCServer(server_addr)
┆ self.server.register_function(sleep, 'sleep')
def run(self):
┆ self.server.serve_forever()
# sleep for random number of seconds
def sleep():
r = random.randint(2,10)
print('sleeping {} seconds'.format(r))
time.sleep(r)
return 'slept {} seconds, exiting'.format(r)
# run server
def run_server(host="localhost", port=8000):
server_addr = (host, port)
thread1 = ServerThread(server_addr)
thread1.start()
print("Server thread started. Testing server ...")
print('listening on {} port {}'.format(host, port))
if __name__ == '__main__':
run_server()
客户:
import xmlrpc.client
server = xmlrpc.client.ServerProxy("http://localhost:8000/", allow_none=True)
print(server.sleep())
print(server.sleep())
print(server.sleep())
print(server.sleep())
问题:
我无法创建全部监听同一端口的多个 ServerThread 实例,并引发异常。
我希望看到所有4个线程并行执行。
我想念什么?接下来有关于GIL的讲座吗?
答案 0 :(得分:2)
您发现的问题是,只能在特定端口上侦听一次。这意味着,除了启动多个线程进行侦听之外,您还需要一个侦听器来将响应委派给不同的线程。
Python提供了现成的multithreaded server,可与SimpleXMLRPCServer
之类的内置服务器类结合使用。
以下代码实现了多线程睡眠服务器,请参见下面的多线程客户端和输出,并注意到服务器和客户端之间的睡眠时间顺序不同。
多线程服务器:
import random
import time
from socketserver import ThreadingMixIn
from xmlrpc.server import SimpleXMLRPCServer
class SimpleThreadedXMLRPCServer(ThreadingMixIn, SimpleXMLRPCServer):
pass
# sleep for random number of seconds
def sleep():
r = random.randint(2, 10)
print('sleeping {} seconds'.format(r))
time.sleep(r)
return 'slept {} seconds, exiting'.format(r)
# run server
def run_server(host="localhost", port=8000):
server_addr = (host, port)
server = SimpleThreadedXMLRPCServer(server_addr)
server.register_function(sleep, 'sleep')
print("Server thread started. Testing server ...")
print('listening on {} port {}'.format(host, port))
server.serve_forever()
if __name__ == '__main__':
run_server()
多线程客户端:
import xmlrpc.client
from concurrent.futures import ThreadPoolExecutor, as_completed
def submit_sleep():
server = xmlrpc.client.ServerProxy("http://localhost:8000/", allow_none=True)
return server.sleep()
with ThreadPoolExecutor() as executor:
sleeps = {executor.submit(submit_sleep) for _ in range(4)}
for future in as_completed(sleeps):
sleep_time = future.result()
print(sleep_time)
服务器输出:
Server thread started. Testing server ...
listening on localhost port 8000
sleeping 3 seconds
sleeping 9 seconds
sleeping 3 seconds
sleeping 10 seconds
127.0.0.1 - - [05/Dec/2018 14:32:02] "POST / HTTP/1.1" 200 -
127.0.0.1 - - [05/Dec/2018 14:32:02] "POST / HTTP/1.1" 200 -
127.0.0.1 - - [05/Dec/2018 14:32:08] "POST / HTTP/1.1" 200 -
127.0.0.1 - - [05/Dec/2018 14:32:09] "POST / HTTP/1.1" 200 -
客户端输出:
slept 3 seconds, exiting
slept 3 seconds, exiting
slept 9 seconds, exiting
slept 10 seconds, exiting