【发布时间】:2014-11-17 20:04:34
【问题描述】:
我需要在 Django 中实现线程。我需要三个简单的 API:
- /work?process=data1&jobid=1&jobtype=nonasync
- /状态
- /kill?jobid=1
API 说明如下:
-
workapi 将采用process并生成一个处理它的线程。现在,我们可以假设它是一个简单的sleep(10)方法。它将线程命名为jobid-1。该线程应该可以通过此名称检索。如果 jobid 已存在,则无法创建新线程。jobtype可以是async,即 api 调用将在生成线程后立即返回http status code 200。也可以是nonasync,这样api就等待服务器完成线程并返回结果。 -
statusapi 应该只显示每个正在运行的进程的状态。 -
killapi 应该基于jobid杀死一个进程。statusapi 不应再显示此作业。
这是我的 Django 代码:
processList = []
class Processes(threading.Thread):
""" The work api can instantiate a process object and monitor it completion"""
threadBeginTime = time.time()
def __init__(self, timeout, threadName, jobType):
threading.Thread.__init__(self)
self.totalWaitTime = timeout
self.threadName = threadName
self.jobType = jobtype
def beginThread(self):
self.thread = threading.Thread(target=self.execution,
name = self.threadName)
self.thread.start()
def execution(self):
time.sleep(self.totalWaitTime)
def calculatePercentDone(self):
"""Gets the current percent done for the thread."""
temp = time.time()
secondsDone = float(temp - self.threadBeginTime)
percentDone = float((secondsDone) * 100 / self.totalWaitTime)
return (secondsDone, percentDone)
def killThread(self):
pass
# time.sleep(self.totalWaitTime)
def work(request):
""" Django process initiation view """
data = {}
timeout = int(request.REQUEST.get('process'))
jobid = int(request.REQUEST.get('jobid'))
jobtype = int(request.REQUEST.get('jobtype'))
myProcess = Processes(timeout, jobid, jobtype)
myProcess.beginThread()
processList.append(myProcess)
return render_to_response('work.html',{'data':data}, RequestContext(request))
def status(request):
""" Django process status view """
data = {}
for p in processList:
print p.threadName, p.calculatePercentDone()
return render_to_response('server-status.html',{'data':data}, RequestContext(request))
def kill(request):
""" Django process kill view """
data = {}
jobid = int(request.REQUEST.get('jobid'))
# find jobid in processList and kill it
return render_to_response('server-status.html',{'data':data}, RequestContext(request))
上面的代码有几个实现问题。线程生成没有以正确的方式完成。我无法在status 函数中检索进程状态。此外,由于我无法从其作业 ID 中获取线程,因此仍然实现了 kill 功能。需要帮助重构。
更新:我做这个例子是为了学习,而不是为了编写生产代码。因此不会支持任何现成的队列库。这里的目标是了解多线程如何与 Web 框架结合使用,以及需要处理哪些边缘情况。
【问题讨论】:
-
试图自己实现这一点是灾难的根源。使用久经考验的现有解决方案 Celery。
-
@DanielRoseman 我不是在这里寻找生产代码。更像是关于线程和 Django 的概念学习。需要使用裸线程库来完成工作。
标签: python django multithreading