2011-12-28 119 views
2

我在项目中使用Python和celery。在项目中,我有两个文件:芹菜工变量共享问题

celeryconfig.py

BROKER_URL = "amqp://guest:[email protected]:5672//" 
CELERY_RESULT_BACKEND = "amqp" 
CELERY_IMPORTS = ("example",) 
CELERYD_CONCURRENCY = 2 

example.py

from celery.task import task 
import hashlib 

md5 = hashlib.md5() 

@task 
def getDigest(text): 
    print 'Using md5 - ',md5 
    md5.update(text) 
    return md5.digest() 

celeryconfig.py,我设置了CELERYD_CONCURRENCY至,这意味着它将二将任务队列中的任务分配给不同的进程。

从一个Python控制台,我跑:

from example import getDigest 
getDigest.delay('foo');getDigest.delay('bar') 

这将创建一个同时由两名工人执行两项任务。 问题是,由于两个工作进程都运行其任务函数[getDigest()],它们似乎使用相同的散列对象(md5)。 芹菜的输出证实了这一点,如下所示。

[PoolWorker-2] Using md5 - 
[PoolWorker-2] <md5 HASH object @ 0x23e6870> 
[PoolWorker-1] Using md5 - 
[PoolWorker-1] <md5 HASH object @ 0x23e6870> 

为了简单起见,我使用hashlib的MD5对象,但是在我的实际项目中,我使用的不能访问和一个以上的过程中被修改的对象。这预计会使工人崩溃。

这提出了一个问题:如何修改我的代码以使工作进程初始化并使用它们自己的(md5)对象?现在,他们共享相同的对象 - 导致我的应用程序崩溃。这可能吗?

回答

5

他们使用相同的对象,因为你明确地告诉他们在你的代码中。通过在任务范围之外创建对象并在任务内使用它,您可以让所有工作人员访问共享对象。这是一个并发问题,不一定是Celery问题。如果对象很小,可以使用该对象的副本,或者使用自己的锁定策略。但是,一般来说,如果一个对象一次被多个进程更新,它需要采用某种同步,这超出了Celery的范围。

+2

它不是同一个对象。芹菜复制过程公关。 worker,在这种情况下给你相同的md5对象标识。 – 2016-08-18 07:04:10