我有一个需要运行优化算法的django应用程序。该算法由两部分组成。第一部分是进化算法,该算法调用第二部分的一定数量的任务,即模拟退火算法。 问题是芹菜不允许任务调用异步任务。 我在下面尝试过以下代码:
sa_list = []
for cromossomo in self._populacao:
sa_list.append(simulated_annealing_t.s(cromossomo.to_JSON(), self._NR, self._T, get_mutacao_str(self._mutacao_SA), self._argumentos))
job = group(sa_list)
result = job.apply_async()
resultados = result.get()
此代码是进化算法的一部分,这是芹菜任务。 当我试图运行它时,芹菜显示这条消息:
尽管只是一个警告,芹菜似乎充满了任务和锁定。[2015-12-02 16:20:15,970:警告/工人-1] /home/arthur/django-user/local/lib/python2.7/site-packages/celery/result.py:45: RuntimeWarning:永远不要在任务中调用result.get()! 见http://docs.celeryq.org/en/latest/userguide/tasks.html#task-synchronous-subtasks
在Celery 3.2中,这将导致异常 提出而不是仅仅是一个警告。
我搜索了很多解决方案,但没有一个解决方案。
答案 0 :(得分:1)
解决这个问题的一种方法是建立一个2阶段管道:
def first_task():
sa_list = []
for cromossomo in self._populacao:
sa_list.append(simulated_annealing_t.s(cromossomo.to_JSON(), self._NR, self._T, get_mutacao_str(self._mutacao_SA), self._argumentos))
job = group(sa_list)
result = job.apply_async()
result.save()
return result.id
然后这样称呼:
from path.to.tasks import app, first_task
result_1 = first_task.apply_async()
result_2_id = result_1.get()
result_2 = app.GroupResult.restore(result_2_id)
resultados = result_2.get()
还有其他方法可以做更多工作 - 您可以使用和弦来收集小组的结果。
答案 1 :(得分:1)
问题不在于celery不允许在您的示例中执行异步任务,而是您将遇到死锁,因此警告:
假设您有一个任务A,它产生了许多子任务B到apply_async()
。这些任务中的每一个都由工人执行。问题是,如果任务B的数量大于可用工作量,任务A仍在等待他们的结果(在您的示例中,至少 - 默认情况下不是这样)。当任务A仍在运行时,执行任务B的工作人员将不执行另一个任务,他们将被阻止,直到任务A完成。 (我不确切知道为什么,但几周前我就遇到了这个问题。)
这意味着在手动关闭工人之前,芹菜不能执行任何操作。
<强>解决方案强>
这完全取决于您对任务结果的处理方式。如果你需要它们来执行下一个子任务,你可以通过Linking with callbacks链接它们或者将它硬编码到相应的任务中(这样你就可以调用第一个,调用第二个,依此类推)。
如果您只需要查看它们是否已执行且是否成功,您可以使用flower来监控您的任务。
如果您需要进一步处理所有子任务的输出,我建议将结果写入xml文件:让任务A调用所有任务B,完成任务后,执行处理结果的任务C.也许有更优雅的解决方案,但这肯定会避免陷入僵局。