2011-12-28 92 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