我是Daemons的新手,我想知道如何让我的主脚本成为守护进程?
我有我的主要脚本,我希望制作一个守护进程并在后台运行:
main.py
def requestData(information):
return currently_crunched_data()
while True:
crunchData()
我希望能够在循环运行时对此守护进程使用requestData函数。我不太熟悉守护进程或如何将我的脚本转换成一个。
但是我猜我必须创建两个线程,一个用于我的cruncData循环,另一个用于守护进程请求接收器,因为守护进程有自己的循环(daemon.requestLoop())。
我目前正在调查Pyro这样做。有没有人知道如何最终使后台运行,而循环有能力接收来自其他进程的请求(比如我想的守护进程)?
答案 0 :(得分:2)
关于在Python中创建守护进程已经有很多问题,例如this one,它很好地回答了这一部分。
那么,你如何让你的守护进程做背景工作?
如您所料,线程是一个明显的答案。但有三种可能的复杂性。
首先,关机了。如果你很幸运,你的crunchData
函数可以在任何时候被立即杀死,没有损坏的数据或(过于重要的)丢失的工作。在那种情况下:
def worker():
while True:
crunchData()
# ... somewhere in the daemon startup code ...
t = threading.Thread(target=worker)
t.daemon = True
t.start()
请注意t.daemon
。 "daemon thread"与您的程序作为守护程序无关;这意味着你可以退出主进程,它将被立即杀死。
但如果crunchData
无法被杀死怎么办?然后你需要做这样的事情:
quitflag = False
quitlock = threading.Lock()
def worker():
while True:
with quitlock:
if quitflag:
return
crunchData()
# ... somewhere in the daemon startup code ...
t = threading.Thread(target=worker)
t.start()
# ... somewhere in the daemon shutdown code ...
with quitlock:
quitflag = True
t.join()
我假设crunchData
的每次迭代都不会花那么长时间。如果是,您可能需要在功能本身内定期检查quitFlag
。
同时,您希望您的请求处理程序访问后台线程正在生成的一些数据。你也需要某种同步。
显而易见的是只使用另一个Lock
。但crunchData
很有可能经常写入其数据。如果它一次保持锁定10秒,请求处理程序可能会阻塞10秒钟。但如果它抓住并释放锁一百万次,那可能需要比实际工作更长的时间。
另一种方法是对数据进行双重缓冲:将crunchData
写入新副本,然后在完成后,暂时抓住锁定并设置currentData = newData
。
根据您的使用情况,Queue
,文件或其他内容可能更简单。
最后,crunchData
可能会做很多CPU工作。您需要确保请求处理程序执行非常少的CPU工作,或者每个请求会因为两个线程争夺GIL而减慢速度。通常这没问题。如果是,请使用multiprocessing.Process
而不是Thread
(这使得在两个进程之间共享或传递数据稍微复杂一些,但仍然不会太糟糕)。