[英]Python multiprocessing: Start/stop processes on server
我正在使用Python构建一个算法交易平台。 多种算法监控市场,并在每天09:30至16:00执行相应的交易。
我正在寻找的是从客户端任意启动和停止算法。 因此,我希望在任何给定时间使用multiprocessing
和客户端运行服务器脚本,该客户端可以启动/停止/列出算法(应该在单独的process
运行)。
如何做到这一点的任何例子? 大多数在线示例都是针对队列服务器的,这似乎不适合我的问题。
编辑:
我正在尝试使用包multiprocessing
。 使用队列的想法对我来说似乎是错误的,因为我知道任意数量的进程将在一整天内运行,或者至少直到我说停止。 我不是试图运行一个简短的脚本,让工作人员在完成上一个工作后从队列中消耗下一个工作。 其实我在考虑使用具有服务器脚本的Manager
,这将永远运行下去,并要求当在单独的进程/线程刚开始新的脚本。 但是,我希望能够向进程发送一个停止信号来杀死它。 我确实有一种感觉,我正在倒退这样做:-)我所拥有的是:
server.py:
import multiprocessing as mp
from multiprocessing import Process
from multiprocessing.managers import BaseManager
from time import strftime
class Server(object):
def __init__(self, port=50000, authkey=''):
self.processes = {}
self._authkey = authkey
self.port = port
self.server = None
self.running = False
BaseManager.register('get_process', callable=lambda: self)
def start_server(self):
manager = BaseManager(address=('', self.port), authkey=self._authkey)
self.server = manager.get_server()
try:
self._logmessage("Server started")
self.running = True
self.server.serve_forever()
except (KeyboardInterrupt, SystemExit):
self.shutdown()
def start_process(self, mod, fcn, *args, **kwargs):
mod = __import__(mod, globals(), locals(), ['object'], -1)
key = "{0}.{1}".format(mod, fcn)
assert not key in self.processes, \
"Process named '%s' already exists" % key
p = Process(target=getattr(mod, fcn), name=mod, args=(None, ), kwargs=kwargs)
self._logmessage("Process '%s' started" % key)
p.start()
# p.join()
self.processes[key] = p
def stop_process(self, key):
self.processes[key].terminate()
del self.processes[key]
def get_processes(self):
return self.processes.keys()
def shutdown(self):
for child in mp.active_children():
child.terminate()
self.server.shutdown()
self.running = False
print "Shutting down"
def _logmessage(self, msg):
print "%s: %s" % (strftime('%Y-%m-%d %H:%M:%S'), msg)
if __name__ == '__main__':
server = Server(authkey='abc')
try:
server.start_server()
except (KeyboardInterrupt, SystemExit):
server.shutdown()
client.py:
from multiprocessing.managers import BaseManager
import time
class Client(object):
def __init__(self, host='', port=50000, authkey=''):
self.host = host
self.port = port
self.manager = None
self.process = None
self._type_id = 'get_process'
self._authkey = authkey
self.manager = BaseManager(address=(self.host, self.port), authkey=self._authkey)
BaseManager.register(self._type_id)
def connect(self):
try:
self.manager.connect()
self._logmessage("Connected to server")
except:
self._logmessage("Could not connect to server")
self.process = getattr(self.manager, self._type_id)()
def start_process(self, mod, fcn):
self.process.start_process(mod, fcn)
self._logmessage("Process '%s' started" % fcn)
def list_processes(self):
print self.process.get_processes()
@property
def connected(self):
return self.manager._state.value == self.manager._state.STARTED
def _logmessage(self, msg):
print "%s: %s" % (time.strftime('%Y-%m-%d %H:%M:%S'), msg)
def test(data):
while True:
print time.time()
time.sleep(1.)
if __name__ == '__main__':
from algotrading.server.process_client import Client
client = Client(authkey='abc')
client.connect()
client.start_process("algotrading.server.process_client", "test")
client.list_processes()
查看Supervisord ,它允许远程管理进程,以及自动启动/重启可配置性。
根据您的可扩展性和灾难恢复需求,您可能正在考虑在运行多个服务器之间分发“监控/交易流程”。 虽然supervisord实际上只是为了管理一台机器,但您可以构建一个管理器应用程序,通过它的xml-rpc界面协调多个服务器,每个服务器都运行supervisord。
Cron或Celery可用于您的每日开始/停止计划。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.