2014-12-11 5 views
5

नीचे मेरी सरल अजगर memcached कोड निहारना atomically एक memcached सूची में कोई आइटम जोड़ने के लिए: अब(अजगर में)

import memcache 
memcache_client = memcache.Client(['127.0.0.1:11211'], debug=True) 
key = "myList" 
obj = ["A", "B", "C"] 
memcache_client.set(key, obj) 

, मान लीजिए मैं myList के रूप में कैश की गई सूची में एक तत्व 'डी' संलग्न करना चाहते हैं , मैं इसे परमाणु रूप से कैसे कर सकता हूं?

मैं जानता हूँ कि यह गलत है क्योंकि यह परमाणु नहीं है:

memcache_client.set(key, memcache_client.get(key) + ["D"]) 

ऊपर बयान एक रेस स्थिति शामिल है। यदि कोई अन्य धागा सही निर्देश पर उसी निर्देश को निष्पादित करता है, तो अपडेट में से एक को गिरफ्तार कर लिया जाएगा।

मैं इस दौड़ की स्थिति को कैसे हल कर सकता हूं? मैं परमाणु रूप से memcached में संग्रहीत एक सूची या शब्दकोश कैसे अद्यतन कर सकते हैं?

+0

https://code.google.com/p/memcached/wiki/NewCommands – user3159253

+0

संभावना इस जवाब, आप 'cas()' (चेक-और-सेट) सरल की का उपयोग करना चाहिए बजाय है 'सेट() ' – user3159253

+0

आप किस पायथन memcache lib का उपयोग कर रहे हैं? – Anentropic

उत्तर

8

यहाँ अजगर ग्राहक एपीआई की इसी समारोह

https://cloud.google.com/appengine/docs/python/memcache/clientclass#Client_cas

इसके अलावा यहाँ है गुइडो van Rossum द्वारा एक nice tutorial है। आशा है कि वह बेहतर अजगर सामान समझाने था मैं से;)

यहाँ कोड आपके मामले में की तरह दिखना चाहिए का तरीका देखें:

memcache_client = memcache.Client(['127.0.0.1:11211'], debug=True) 
key = "myList" 
while True: # Retry loop, probably it should be limited to some reasonable retries 
    obj = memcache_client.gets(key) 
    assert obj is not None, 'Uninitialized object' 
    if memcache_client.cas(key, obj + ["D"]): 
    break 

पूरे कार्यप्रवाह ही रहता है: पहले आप एक मूल्य लाने (डब्ल्यू कुछ/एक कुंजी से जुड़ी आंतरिक जानकारी), फिर प्राप्त मूल्य को संशोधित करें, फिर इसे memcache में अद्यतन करने का प्रयास करें। एकमात्र अंतर यह है कि मान (वास्तव में, कुंजी/मूल्य जोड़ी) की जांच की जाती है कि इसे समांतर प्रक्रिया से एक साथ बदल नहीं दिया गया है। बाद के मामले में कॉल विफल हो जाती है और आपको शुरुआत से वर्कफ़्लो को पुनः प्रयास करना चाहिए। इसके अलावा, यदि आपके पास बहु-थ्रेडेड एप्लिकेशन है, तो प्रत्येक memcache_client उदाहरण संभवतः थ्रेड-स्थानीय होना चाहिए।

यह भी मत भूलना कि सरल पूर्णांक काउंटर के लिए incr() और decr() विधियां हैं जो उनकी प्रकृति द्वारा "परमाणु" हैं।

+0

क्या आप कृपया दिखा सकते हैं कि मुझे उपरोक्त मेरे मामले में कैस स्टेटमेंट का उपयोग कैसे करना चाहिए? दस्तावेज़ों में एक उदाहरण नहीं है। साथ ही, यदि संभव हो तो दिखाएं कि कैसे (पायथन में) परमाणु रूप से memcached में संग्रहीत शब्दकोश में एक कुंजी/मान जोड़ें। –

+1

नोट 'get'/'cas' वाक्यविन्यास' pylibmc' का उपयोग करते हुए थोड़ा अलग है http://sendapatch.se/projects/pylibmc/reference.html – Anentropic

-2

यदि आप दौड़ की स्थिति प्राप्त नहीं करना चाहते हैं तो आपको थ्रेडिंग मॉड्यूल से लॉक आदिम का उपयोग करना होगा। उदाहरण के लिए

lock = threading.Lock() 

def thread_func(): 
    obj = get_obj() 
    lock.acquire() 
    memcache_client.set(key, obj) 
    lock.release() 
+0

अभी भी memcache सर्वर – Anentropic

+0

@Anentropic Saqib के _other_ क्लाइंट के साथ रेस स्थिति है अली ने कई सर्वरों के बारे में नहीं पाइथन धागे के बारे में पूछा, इसलिए यदि वह कई धागे के साथ केवल एक क्लाइंट का उपयोग करेगा तो मेरा जवाब अभी भी मान्य है। –