Celery: 不允许任务启动子流程

创建于 2013-11-29  ·  68评论  ·  资料来源: celery/celery

从Celery 3.1.0开始,进程池( celery.concurrency.prefork ,以前的celery.concurrency.processes )使用守护进程执行任务。

守护进程不允许创建子进程,因此使用multiprocessing软件包的任务无法正常工作:

[2013-11-29 14:27:48,297: ERROR/MainProcess] Task app.add[e5d184c0-471f-4fc4-804c-f760178d4847] raised exception: AssertionError('daemonic processes are not allowed to have children',)
Traceback (most recent call last):
  File "/Users/aromanovich/Envs/celery3.1/lib/python2.7/site-packages/celery/app/trace.py", line 218, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/Users/aromanovich/Envs/celery3.1/lib/python2.7/site-packages/celery/app/trace.py", line 398, in __protected_call__
    return self.run(*args, **kwargs)
  File "/Users/aromanovich/Projects/celery/app.py", line 10, in add
    manager = multiprocessing.Manager()
  File "/usr/local/Cellar/python/2.7.6/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/__init__.py", line 99, in Manager
    m.start()
  File "/usr/local/Cellar/python/2.7.6/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/managers.py", line 524, in start
    self._process.start()
  File "/usr/local/Cellar/python/2.7.6/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/process.py", line 124, in start
    'daemonic processes are not allowed to have children'
Not a Bug

最有用的评论

@thedrow
你误会了。 两次。
我们关心的不是您没有资源(这是完全可以理解的,可悲的是,这在自由软件中很常见)。 我们担心的是票证因此而关闭,这不是票证的工作方式。
我们不是“不快乐”,我们感到震惊。

所有68条评论

这在3.0和3.1之间没有变化,因此我不确定为什么现在而不是以前会出现此错误。

这就是如何重现此错误。

app.py:

import multiprocessing
from celery import Celery

app = Celery(__name__, broker='amqp://192.168.33.40')
@app.task
def f():
    manager = multiprocessing.Manager()

sendtask.py:

import app

app.f.delay()

我使用以下命令运行worker: celery worker -A app.app -l debug

使用Celery 3.0.24,任务成功:

[2013-12-02 20:43:56,454: INFO/MainProcess] Task app.f[bcaab028-dbec-43a8-9259-ff7c35ff13d0] 
succeeded in 0.0169339179993s: None

使用Celery 3.1.5时,它不会:

[2013-12-02 20:48:38,946: ERROR/MainProcess] Task app.f[c9f1cdd3-ae38-493e-b7c7-b9636ed473d0] 
raised exception: AssertionError('daemonic processes are not allowed to have children',)

我对这个问题的理解如下: celery.concurrency.prefork.TaskPool使用celery.concurrency.asynpool.AsynPool ; AsynPoolbilliard.pool.Pool AsynPool继承而来的,它会生成守护进程工作进程,AsynPool不会覆盖此行为。 但是您是对的,这种方案在3.0和3.1之间似乎没有改变,所以我也很困惑:)

似乎我并不孤单地遇到这个问题: http :

一个区别是工作进程现在是'Process'的子类,在它使用函数参数Process(target=) ,这些方法的默认值可能有所不同。

我认为任务进程是守护进程,这严重限制了任务的执行。
我编写了一个任务,该任务使用多处理来加速CPU绑定的操作。 当我在终端中启动工作程序时,一切工作正常,如下所示:

芹菜工人--app =任务-Q wb -l信息--concurrency = 1

但是,当我使用celeryd脚本启动工作程序时,出现以下异常:
AssertionError:守护进程不允许有子进程

我弄清楚是什么导致了行为的改变。
在3.0和3.1中都使用守护进程运行任务,但是直到celery / billiard @ 4c32d2ehttps://github.com/celery/billiard/commit/c676b94aa4144349b11ab31c82296a5d804909c9 multiprocessing模块都不知道,因此允许创建子流程。

据我了解,版本3.1之前存在一个错误(允许任务创建子流程,这可能导致孤立状态),现在此错误已得到修复。

对我来说,不允许python守护进程分叉的决定似乎很武断。 虽然我认识到它的真诚,但我觉得如果我愿意的话,我应该可以完全控制这种行为。

对每个任务只能绑定到一个进程似乎对我来说是一个严重的局限。 有什么想法吗?

我不知道为什么首先要有这种限制,我可以理解的警告是,当您完全能够使用其他方法来分叉进程时,完全禁止这样做似乎很愚蠢。

@ask ,可以用守护程序标志为False初始化celery worker进程吗? 还是使它可配置?

@ilyastam似乎我们在同时评论

我同意这似乎是一个任意限制,但是我希望我知道首先添加它的理由。

这是posix系统中众所周知的陷阱,但仍然允许。 您可以在信号处理程序中清理子进程,尽管这不能保护您免受SIGKILL的侵害。

我认为我们应该消除台球的限制,即使这会与多处理行为有所不同。 您仍然可以使用subpocess模块或使用低级fork调用来创建子进程,因此高级用户应该可以创建子billiard.Process实例。

@ilyastam应该能够删除raise语句,而不必使进程成为“非守护程序”

也就是说,即使后台进程无法获得它们,也将被允许创建子进程,
posix仍然是这样工作的。

顺便说一句,请注意,这不是raise ,它是一条assert语句,如果以PYTHONOPTIMIZE envvar或-O参数启动python,则该语句将被删除。

台球3.3.0.11在PyPI上,包括此更改

@问谢谢。 知道什么版本的芹菜会有所改善吗?

multiprocessing文档明确指出不允许守护进程创建子进程,并说明原因。 对我而言,assert语句看起来更像是放在这里作为raise的快捷方式(人们经常这样做)。

此限制已记录在案,我认为Celery静静地修补multiprocessing并将其拿走对于Celery来说不是一个好主意。 这可能会导致真正意想不到的有害后果。

我可以想到以下示例(尽管看起来有些虚构):

@app.task
def f():
    p = multiprocessing.Pool(3)
    p.map_async(time.sleep, [1000, 1000, 1000])

作为普通的Python函数运行,此代码可以正常工作。 但是作为Celery任务(使用Celery 3.0。*版)运行时,它将留下三个子进程,这些子进程将永远挂起。 当芹菜工人辞职时,这些子流程将变成孤立的。

它没有说明原因,仅说明了启动子进程时您期望的unix行为。 即使在unix中这是一个臭名昭著的限制,它也不会阻止人们这样做。 这跟没什么不同
开始subprocess.Popen进程,甚至调用fork()开始新的进程。 那么为什么它应该是非法的呢?

举例说明:

from billiard import Pool
from multiprocessing.util import Finalize

_finalizers = []

@app.task
def f():
    p = billiard.Pool(3)
    _finalizers.append(Finalize(p, p.terminate))
   try:
       p.map_async(time.sleep, [1000, 1000, 1000])
       p.close()
       p.join()
   finally:
       p.terminate()

要杀死(-9),您还必须杀死-9子进程,但这就是您将要拥有的东西
考虑所有的Unix进程。

我并不是在提倡为每个任务创建一个Pool,而是我不明白为什么知道他们是什么的用户
这样做,不应被允许从任务开始流程。

此外,我们不给猴子打补丁,这只是台球的一种变化。

此外,我们不给猴子打补丁,这只是台球的一种变化。

“猴子修补”是指此任务,将multiprocessing._current_process替换billiard.process.Process的实例: https :

我同意,如果正确处理了子进程,那么启动子进程就没有什么问题(例如您的示例)。 我的观点是, multiprocessing并不是这样写的,我们不应该忽略它的_implementation_限制。

@aromanovich不能用其他任何方式编写,这不是多重处理的限制,而是unix的限制。

它设置_current_process,以便日志记录模块processName format变量起作用,并且台球进程对象与多进程进程对象具有相同的API,因此可以安全地设置当前进程。

顺便说一句,您必须使用台球来解除限制,使用多处理仍会引发异常。

也可以使用以下方法解决此问题:
http://stackoverflow.com/questions/6974695/python-process-pool-non-daemonic
这将使用户能够继续使用多处理模块,从而避免出现此问题:
https://github.com/celery/billiard/issues/99

当从celery任务中调用@parallel织物任务时,出现此错误。

@celery.task
def dostuff():
   execute(fabfile.push_settings, sid=site['sid'])

<strong i="7">@parallel</strong>
@roles(environment)
def push_settings(sid):
  #do stuff

@frodopwns使用ENV
导出PYTHONOPTIMIZE = 1
删除此断言。 您需要处理所有事情。

@xiaods我想我用这样的东西解决了这个问题:

@worker_process_init.connect
def configure_workers(sender=None, conf=None, **kwargs):
    Crypto.Random.atfork()

问题

我有一个任务,该任务计算一些数据并加载scikit-learn分类器以基于该数据进行预测。 当我自己运行任务时,一切都很好,但是当我使用Celery运行它时,当任务尝试加载腌制的分类器时,我得到一个错误:

[2015-07-17 21:23:51,299: ERROR/MainProcess] Task app.f[329d0da4-2e0e-4e1f-8148-d64f47750b1f] raised unexpected: AttributeError("'Worker' object has no attribute '_config'",)
Traceback (most recent call last):
  File "/home/username/anaconda3/lib/python3.4/site-packages/celery/app/trace.py", line 240, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/home/username/anaconda3/lib/python3.4/site-packages/celery/app/trace.py", line 438, in __protected_call__
    return self.run(*args, **kwargs)
  File "/home/username/working/playground/celery/app.py", line 11, in f
    clf = pickle.load(open('clf.pickle', 'rb'))
  File "/home/username/anaconda3/lib/python3.4/site-packages/sklearn/ensemble/__init__.py", line 6, in <module>
    from .base import BaseEnsemble
  File "/home/username/anaconda3/lib/python3.4/site-packages/sklearn/ensemble/base.py", line 13, in <module>
    from ..externals.joblib import cpu_count
  File "/home/username/anaconda3/lib/python3.4/site-packages/sklearn/externals/joblib/__init__.py", line 112, in <module>
    from .parallel import Parallel
  File "/home/username/anaconda3/lib/python3.4/site-packages/sklearn/externals/joblib/parallel.py", line 23, in <module>
    from ._multiprocessing_helpers import mp
  File "/home/username/anaconda3/lib/python3.4/site-packages/sklearn/externals/joblib/_multiprocessing_helpers.py", line 25, in <module>
    _sem = mp.Semaphore()
  File "/home/username/anaconda3/lib/python3.4/multiprocessing/context.py", line 81, in Semaphore
    return Semaphore(value, ctx=self.get_context())
  File "/home/username/anaconda3/lib/python3.4/multiprocessing/synchronize.py", line 127, in __init__
    SemLock.__init__(self, SEMAPHORE, value, SEM_VALUE_MAX, ctx=ctx)
  File "/home/username/anaconda3/lib/python3.4/multiprocessing/synchronize.py", line 59, in __init__
    kind, value, maxvalue, self._make_name(),
  File "/home/username/anaconda3/lib/python3.4/multiprocessing/synchronize.py", line 117, in _make_name
    return '%s-%s' % (process.current_process()._config['semprefix'],
AttributeError: 'Worker' object has no attribute '_config'

重现

创建一个空的分类器并将其另存为泡菜:

import pickle
from sklearn.ensemble import GradientBoostingClassifier
clf = GradientBoostingClassifier()
pickle.dump(clf, open('clf.pickle', 'wb'))

创建一个简单的应用程序( app.py ):

import pickle
import sklearn
from celery import Celery

app = Celery(__name__, broker='amqp://localhost//')

@app.task
def f():
    print('hello')
    clf = pickle.load(open('clf.pickle', 'rb'))
    print(clf)

启动芹菜工作者:

celery -A app worker --loglevel=debug

运行应用程序:

python -c "from app import f; f.delay()"

错误信息:

...
AttributeError: 'Worker' object has no attribute '_config'

解决方案

我认为应该有一个“ monkeypatch” Celery选项,以允许任务启动子流程,特别是如果过去存在这样的“功能”。 现在,当人们遇到此问题时,他们只是在转向其他框架: http : http :

此问题应重新打开...

我只是遇到了同样的问题。 我在我的一个工人中使用nltk ,而后者又导入了scikit-learn ,导致出现同样的错误@ostrokach显示。

看来我可以使用以下代码解决此问题:

from celery.signals import worker_process_init

@worker_process_init.connect
def fix_multiprocessing(**kwargs):
    from multiprocessing import current_process
    try:
        current_process()._config
    except AttributeError:
        current_process()._config = {'semprefix': '/mp'}

显然这是一个非常粗糙的技巧,我不知道如果我真的要使用多处理功能(我什至不知道semprefix是什么)会发生什么,但这足以使scikit-learn再次工作。

我将其留给其他在同一问题上迷迷糊糊直到解决此问题的其他人。

这可能与Python 3上的台球不兼容吗? 还是可以在Python 2上重现?

芹菜制程最初无法建立子程序的问题仍然存在吗? 通过评论回顾,该问题已在celery / billiard @ e6bb0f7版本3.3中

@martinth谢谢,这个hack也对我

@xiaods谢谢! 您的解决方案对我有用! 谢谢!

@ gilinson仍然是一个问题,并且导出PYTHONOPTIMIZE = 1仍然可以“修复”它。
只是遇到了同样的问题,试图在Celery任务中运行ansible剧本

@martinth感谢您的入侵! 我遇到了同样的问题:

  • 的Python 3.4.3
  • 芹菜== 3.1.18
  • scikit-learn == 0.17

@martinth的hack对我不起作用,遇到了这种尝试使用多处理来加快计算速度的问题。 取而代之使用了线程模块,这似乎为我减轻了这个错误,同时仍然中断了我的处理。

使用基于线程的multiprocessing.dummy在芹菜中为我工作:

from multiprocessing.dummy import Pool

同样在python 2.7.5中仍然发生此错误。 我不确定它是否打算解决这个问题,但是这使得使用Saltstack的salt-ssh无法与芹菜一起使用。

由于我们没有足够的资源来完成此任务,因此请关闭该窗口。

可能的“解决方案”

我有一个尝试创建线程的任务,但这会失败。 我设法通过以下方式使其工作:分叉到一个bash脚本,该脚本本身派生至执行相同精确代码的python解释器(因此可能创建线程,这对于我的用例而言至关重要)。

我不明白为什么门票被关闭。 如果您没有足够的资源,则可以对此发表评论,但这不会关闭故障单。 您只是在隐藏这样做的错误。

对于优先级和严重性均标记为“严重”的故障单而言,这尤其不利。

@orzel +1。
优先级:关键
严重程度:严重
由于我们没有足够的资源来完成此任务,因此请关闭该窗口。

那是个玩笑。 如果您现在没有资源-那就不要立即修复它。 有资源时将其修复。 关闭车票不会解决问题

@orzel @Templarrr我将此票标记为“紧急”,因此这里不要责怪@ask
您可能对此不满意,但抗议无济于事。
我们需要根据什么是可行的,什么是不可行的以及当前是不是可行的来整理待办事项。
这是一个艰难的要求,但必须有人做到。
如果您遇到此问题,请尝试解决它。 我保证,如果修复程序正确且具有适当的测试,我将对其进行合并。

@thedrow
你误会了。 两次。
我们关心的不是您没有资源(这是完全可以理解的,可悲的是,这在自由软件中很常见)。 我们担心的是票证因此而关闭,这不是票证的工作方式。
我们不是“不快乐”,我们感到震惊。

我也完全不同意关闭此操作。

我认为我们都可以同意这确实是一个错误。 虽然确实很遗憾,没有足够的资源来关闭_definite_错误,但这无济于事。 您可能无法知道是否明天某人会花很长时间,认为“让我们修复Celery中的一些错误”只是为了浏览未解决的问题,并认为“嗯,这里没有任何有趣的工作...让我们工作在_OtherProject_上”。
此外,解决此问题将使查找它变得更加困难。 我不知道您如何使用Github,但是当我发现潜在问题时,我首先在问题跟踪器中搜索未解决的问题。 通常,会有很多讨论,而且永远不会有我现在可以使用的解决方法(例如在这种情况下)。 只有当我变得极度绝望时,我才开始浏览已解决的问题。

这不是“积压整理”,而是数字调整。 如果我查看使用的东西,我会查看未解决的问题数,但我也会始终查看星级数(对于芹菜来说这是很高的)。 我知道,为了吸引公众以及为了您自己,减少bug数量是可取的。 老实说,我知道看到“ 250个未解决的问题”并不是一个好数字,听起来让人不知所措。

如果您没有人力在下个月(或什至一年)内进行此工作,那就没问题了。 只是不要关闭。 仅当问题已解决或绝对要解决时,才发生关闭。 两者都不是这里。

只需删除“关键”标志并为现在无法处理但如果资源可用则应处理的任何内容添加“已延迟”标志。

我不确定我们是否可以实际解决此问题。 我们无法更改Unix的工作方式,但可以向上游提交补丁以解除限制?

也许Linux中有特定于平台的解决方案,但这必须进行研究。 它已经开放了2年,没有任何人愿意修复它,因此不太可能在近期功能中进行修复。

我关闭了200多个问题,并将超过3万封电子邮件标记为已读,因此其中一些必然会引起争议,因此我们可能不得不重新打开它们。 我完全希望如此,但是如果我们也可以为解决方案做出贡献,那就太好了,例如,如果这是唯一已知的选择,则可以帮助记录缺陷。

我们忙于工作,试图在没有资源的情况下运行一个庞大的项目。 我们无法分类问题,也无法找出已解决的问题。

哦,那好吧。 但是至少可以记录一下“如果您为芹菜工人编写代码,则不能使用多处理”这一事实? 我的意思是……总会有一些人不读它,但至少您可以指向它并说:“看,它已被记录在案。我们无法更改。请处理它。”

我的待办事项清单非常庞大,您现在可以直接在github上编辑文档,因此很容易做出如下更改:(

我这样做并不是为了隐藏问题,而是为了使人们采取行动,正是因为我希望看到这种情况有所改善。

@ask我们可以在Django中使用celery在任务内部应用多处理吗?
还有其他选择吗?

@abhisheksachan,您应该在发布此类问题之前阅读所有此问题

@abhisheksachan我已经https://pypi.python.org/pypi/billiard使它工作了,因为它允许守护子进程。

是的,您必须将“多处理”中的导入替换为“台球”,例如:

from multiprocessing import Process

->

from billiard import Process

我们无法禁用多处理限制,但是我们认为无论如何都不应存在限制,因此我们的多处理派生可以允许它。

对于像我这样投资开发排队系统_BEFORE_的人,要找出该限制并需要一个不同的解决方法,直到他们可以迁移到更有用的RabbitMQ python包装器上,我设法通过调用一个外部子进程来解决该问题。干净地叉自己。 该分叉的过程现在不在芹菜沙箱中,并且一切正常。

在OP示例中,替换为:

app = Celery(__name__, broker='amqp://192.168.33.40') 
@app.task
def f():
    manager = multiprocessing.Manager()

和:

app = Celery(__name__, broker='amqp://192.168.33.40')
@app.task
def f():
    process = subprocess.Popen(["program"]) # or the newer post 3.5 run version
    process.wait()
    # analyze exit code

并且“程序”将看起来像(在POSIX unix / linux平台下)

import os

def main():
      manager = multiprocessing.Manager()

# this is equivalent to "(cmd )&" under bash
pid = os.fork()
if pid == 0:
    cpid = os.fork()
    if cpid == 0:
        main()
    else:
        exit(0)
else:
    os.wait(pid)

请记住,CPU管理超出了celery的范围,这有点违背使用celery的想法,但是考虑到要使用多处理,您可能无论如何都想处理芹菜之外的CPU使用情况。

至少应记录该限制。 我在文档中环顾四周,找不到。

同样,随时随文档更改提交拉取请求。

跟进@martinth评论,关于Python 3.5.2,Celery 4.0.0和台球3.5.0的问题,他的解决方案不起作用,因为多进程检查正在守护的进程并阻止其启动子进程。

我能够通过重置工作程序的守护程序标志来解除限制。 我敢肯定这是个坏主意,但是它允许从芹菜任务中启动多处理。

@worker_process_init.connect
def fix_multiprocessing(**kwargs):
    # don't be a daemon, so we can create new subprocesses
    from multiprocessing import current_process
    current_process().daemon = False

就是说,恕我直言,芹菜应该添加一个文档化的选项,以配置是否启动工作人员为重罪。 请注意,我在k8吊舱中使用celery,因此celery是使用celery worker作为前台进程启动的,我真的不需要想要守护程序的工人。

@miraculixx这个建议的问题是,我们将有更多的失败模式要处理,还有更多的问题要解决。 我们宁愿避免这些。

尽管将多处理与预叉池结合使用失败,但是在使用独奏池时似乎可以使用。 因此,我猜想一种解决方法是,在单独的分叉池中产生多个芹菜工人,而不是在多个分叉池中产生多个孩子。 这听起来合法吗? 当然,那样的话,某些选项(例如,每个孩子的max-mem-mem)将不起作用。

我认为这基本上是一个应用程序设计问题。 面对daemonic processes are not allowed to have children ,这是一个特殊的痛苦,因为您知道,当您不得不重新设计整个应用程序时,已经到了一个地步。 但这是操作系统级别的限制,您不能在没有严重副作用的情况下规避它。 守护进程也不能在C中有子级。这不是特定于Python的东西。 曾经有过关于线程与进程性能的争论,得出的结论是,它们中的任何一个都不比另一个更好或更差。

我建议两种选择(一般来说,这里不谈论芹菜)

  • 使用subprocess.Popen产生一个独立的进程,该进程可以具有子进程,并使用UNIX套接字进行进程间通信
  • 由派生的进程而不是您的主进程派生线程真的必要吗?

对于它的价值,当时我的用例是我想启动一个长时间运行的子流程,该子流程由于非平凡(且对安全性不敏感)的输入问题而经常崩溃。 因此,其想法是至少确保该过程成功启动。

从长远来看,由于各种原因,它的设计很糟糕,因此新架构自然地恢复为异步芹菜工作者的“自然”使用。 因此,我同意质疑是否真的有必要进行分叉的想法。 任务是分叉。

对于它的价值,我的用例是启动使用多处理(通过joblib)的scikit-learn流程。 从那以后,我已经开发了一个针对joblib的celery后端,这意味着scikit-learn使用celery启动了并行进程,并且不再需要我的上述技巧。 目前处于POC阶段,尚未准备好黄金时段。

@miraculixx您将此托管在某个地方吗? 我想看看和/或尝试一下。 我遇到了与您相同的问题-sklearn生成子流程-我基本上已经放弃了Celery。

@pgeez如果您不关心在sklearn中使用子流程,则可以设置环境变量JOBLIB_MULTIPROCESSING = 0。 参见https://github.com/scikit-learn/scikit-learn/blob/0.18.X/sklearn/externals/joblib/_multiprocessing_helpers.py

@jennaliu感谢您的想法,但是像@miraculixx一样,我需要启用多处理功能。

你们是否尝试过使用旧的Unix双叉把戏来使孩子脱离celery的守护进程?

您是否读过该主题的标题?!?!?

@sebastroy显然,我多年来一直在关注该主题。 我刚刚发现了叉,但是现在我发现我的困惑是在以为芹菜叉被守护进程杀死了,而不是被人们完全阻止了。

知道了是的,我前世使用C语言,所以就像面包和黄油。

我正在使用的解决方法是subprocess.Popen,它可以正常工作,但是您需要重新实现一些逻辑(并制作程序的Shell版本),而这正是celery应该做的。 但是我通过更改顶级API实现的行为来解决此问题。 我认为这更符合芹菜的目的。 底层也简化了一些逻辑。

幸运的是,当我尝试在Celery任务中运行ansible剧本时,我发现了这个问题。
@martinth提供的方法不适用于我。 我打印current_process()._config并得到
{'authkey': b"y&e\x8d'\xcb\xd4\r\xd2\x86\x06\xe7\x9e\x14\xaf \xbc\xc4\x95\xa5G\xec&[i\x19\xf3G-\x06\xac\x19", 'semprefix': '/mp', 'daemon': True}
然后,我将字段daemon重新分配给False ,它可以工作。

是否有一些解决方案或其他实现可允许在任务中运行多进程?

@HeartUnchange :最近,我们正在努力进行一个大数据项目,我们希望使用celery作为分布式组件。 在您的指导下,我们很幸运能够解决问题。 查看任务配置:

     @app.task
    def handleBigZipfile(filename,nid):
    current_process()._config['daemon'] = False
    logger.info('{} begin handle!'.format(filename))
    handleAll(filename,nid)
     logger.info('{} is done!'.format(filename))

解决方案还可以! 我们从2017.1开始项目,现在原型已经完成! 九个月过去了! 我感谢你! 而我的谢意却无法表达!
请您介绍一下您如何解决该问题! 我们渴望知道这一点!

你好 ,

我有一个非常标准的设置:Django + Rabbitmq + celery-4.0.2 + python-2.7 + centOS-7

我正在尝试使用celery中的标准python多处理模块生成一个进程。

守护进程不允许创建子进程,因此使用多处理程序包的任务无法正常工作:
用于运行的命令:celery worker -B -A celery_task -l debug
追溯日志:

[2017-09-26 23:27:08,838: WARNING/PoolWorker-2] ERROR
[2017-09-26 23:27:08,839: WARNING/PoolWorker-2] Traceback (most recent call last):
[2017-09-26 23:27:08,839: WARNING/PoolWorker-2] File "/home/induser/config.py", line 612, in main
[2017-09-26 23:27:08,840: WARNING/PoolWorker-2] mylog_process = mp.Process(target=test_logger_process, args=(myqueue,))
[2017-09-26 23:27:08,840: WARNING/PoolWorker-2] File "/usr/lib64/python2.7/multiprocessing/process.py", line 98, in __init__
[2017-09-26 23:27:08,841: WARNING/PoolWorker-2] self._authkey = _current_process._authkey
[2017-09-26 23:27:08,841: WARNING/PoolWorker-2] AttributeError: 'Process' object has no attribute '_authkey'

不产生该进程的原因可能是什么?
这是代码:

import multiprocessing as mp
from celery.schedules import crontab
from celery.decorators import periodic_task

@periodic_task(run_every=crontab(minute='*/1'), name='test_process_celery')
def main():
data = config_read()
try:
    myqueue = mp.Queue(-1)
    mylog_process = mp.Process(target=test_logger_process, args=(myqueue,))
    mylog_process.start()
    . . .
    . . .
except Exception as e:
    raise
finally:
    mylog_process.join()

谢谢。

尝试掌握并报告是否仍然是问题

它仍然有错误。 我尝试将子流程用于:

from multiprocessing import Process, Value
import ctypes

[...]
        result = Value('i', 0)
        text = Value(ctypes.c_char_p, fail_string.encode())
        p = Process(target=reader.find_text_async, args=(result, text, ))
        p.start()
        p.join(5)

        if p.is_alive():
            logging.WARNING("Manual terminating the process 'find_text_async'")
            p.terminate()

但是对于芹菜主分支说:

在开始的文件“ /usr/lib/python3.5/multiprocessing/process.py”,第103行
“守护进程不允许有孩子”
AssertionError:守护进程不允许有子进程

编辑

我更改了台球的多重处理功能,并且可以正常工作!

from billiard import Process, Value

此页面是否有帮助?
0 / 5 - 0 等级