如何立即退出python程序但仍然让线程完成

时间:2016-06-02 11:36:06

标签: python multithreading

我正在编写某种插件,需要快速返回以避免调用程序超时,调用程序以足够长的间隔调用它来准备数据,但是准备信息需要比允许的超时时间长一点,所以我从缓存文件返回信息并启动一个线程,以便下次更新缓存文件。 但问题是,主文件可以/可能不会退出,直到线程完成,这使整个想法无效。 将线程设置为守护程序没有帮助。守护进程模式允许程序快速返回,但是线程只是在完成之前被杀死,非守护进程模式阻止程序快速返回直到线程完成。

有没有办法立即退出程序,但仍然让线程完成其业务?

#!/usr/bin/python

import time
import threading


def getinfofromcachefile():
  print "This is very fast"
  data = { "msg" : "old data" }
  return data

def getfreshinfo():
  time.sleep(5)
  print "This takes a long time"
  time.sleep(10)
  data = { "msg" : "fresh data" }
  return data

def update_cachefile():
  data = getfreshinfo()
  print "The data is now ready"
  print data

def getinfo_fast():
  data = getinfofromcachefile()

  d = threading.Thread( name='update cache', target=update_cachefile )
  d.setDaemon(False)
  d.start()

  return data


print getinfo_fast()

使用setDaemon输出示例(False):

user@server:/home/ubuntu# time ./snippet 
This is very fast
{'msg': 'old data'}
This takes a long time
The data is now ready
{'msg': 'fresh data'}

real    0m15.022s
user    0m0.005s
sys 0m0.005s

使用setDaemon(True)输出示例:

user@server:/home/ubuntu# time ./snippet 
This is very fast
{'msg': 'old data'}

real    0m0.010s
user    0m0.000s
sys 0m0.010s

后者快速返回,但线程刚被杀掉

2 个答案:

答案 0 :(得分:1)

在我看来,你需要的不仅仅是线程。如果您需要从主程序中快速终止并运行长时间的后台任务,则需要进行分叉。我现在无法测试,但我认为你应该尝试:

from multiprocessing import Process

#...

def getinfo_fast():
    data = getinfofromcachefile()

    p = Process(target=update_cachefile)
    p.start()
    # no join hence main program terminates
    return data

print getinfo_fast()

答案 1 :(得分:0)

Arthur的想法"不仅仅是线程",让我偶然发现 python-daemon , 这对我有用。我的程序现在执行getinfo_fast函数,然后立即返回到提示符,但getfreshinfo()在后台执行。

https://pypi.python.org/pypi/python-daemon

import daemon

#...

print getinfo_fast()

with daemon.DaemonContext():
  getfreshinfo()