多线程XML-RPC(python3.7.1)

时间:2018-12-04 21:28:17

标签: python python-multithreading simplexmlrpcserver

服务器:

  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的讲座吗?

1 个答案:

答案 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