2011-12-13 5 views
5

मेरे पास एक वेब सर्वर Python में चल रहा है। सर्वर निजी है, इसलिए मैं केवल 20 उपयोगकर्ताओं से कनेक्ट होने की अपेक्षा करता हूं। सर्वर बहु-थ्रेडेड (इस समय 8 कोर, इसलिए 8 धागे मैंने अनुमान लगाया है)।आप इस पायथन शब्दकोश थ्रेड-सुरक्षित कैसे बनाएंगे?

जब अनुरोध आते हैं, तो मैं उपयोगकर्ताओं की पहचान करने में सक्षम हूं। कुछ प्रश्नों पर, मुझे उपयोगकर्ता नाम -> बूलियन के एक साधारण dictionary को अद्यतन करने की आवश्यकता है। मैं यह धागा कैसे सुरक्षित कर सकता हूं?

+0

क्या आप स्वयं सर्वर को कार्यान्वित कर रहे हैं या आप django, पिरामिड या मोड़ जैसे कुछ उपयोग कर रहे हैं? – dirk

+0

यह चेरीपी है, संस्करण 3.2 – Jerome

उत्तर

5

आप एक ताला (दौड़ की स्थिति Joonas वर्णित से बचने के लिए) की जरूरत है, और,, अजगर 2.4 के साथ फंस रहे हैं

import threading 
lock = threading.Lock() 

shared_dict = {} 

def do_thing(user, value): 
    lock.acquire() 
    try: 
     shared_dict[user] = value 
    finally: 
     # Always called, even if exception is raised in try block 
     lock.release() 
+0

मान लें कि मेरा लेखक उस लॉक के तहत अपने संशोधनों को लपेटता है। क्या पाठक इसे जारी होने तक प्रतीक्षा करेगा, यानी लेखन समाप्त हो गया है? या क्या मुझे उसमें पढ़ने को लपेटने की ज़रूरत है? – Jerome

+0

@ जेरोम जी आपको शायद पढ़ने के लिए एक समान लॉक फ़ंक्शन होना चाहिए (फिर से "केवल पढ़ने-संशोधित-लिखने" दौड़ की स्थितियों से बचने के लिए) – dbr

2

शब्दकोश को अपडेट करने से पहले threading.LOCK.acquire() का उपयोग करें और थ्रेडिंग का उपयोग करें .LOCK.release(), एक बार जब आप इसे अपडेट कर लेंगे।

+0

यह अजीब बात है, मैंने लॉक ऑब्जेक्ट को शब्दकोश में विशिष्ट होने की उम्मीद की होगी, जावा में सिंक्रनाइज़ ऑब्जेक्ट/ब्लॉक/विधि की तरह थोड़ा ... मैं उलझन में हूं – Jerome

8

आपको वैश्विक लॉक ऑब्जेक्ट बनाना होगा।

lock = threading.Lock() 

फिर शब्दकोश के प्रत्येक एक्सेस के आसपास लॉक प्राप्त करने और रिलीज़ करने के लिए। ऐसा करने का सबसे आसान तरीका नया (आईएसएच) with syntax के साथ है।

with lock: 
    dict[key] = value 
+0

मैं प्रतिबंधित हूं पायथन 2.4 का उपयोग, क्या यह उपलब्ध नहीं होगा? – Jerome

+0

नहीं, साथ उपलब्ध नहीं है, लेकिन आप lock.acquire() और lock.release इसके बजाय() का उपयोग कर सकते हैं। –

4

आप या Boolean कैसे अद्यतन किया जाता है पर निर्भर करता है, एक ताला उपयोग करने की आवश्यकता नहीं हो सकता है।

Booleanका मूल्य नहीं पिछला मान पर निर्भर करता है, तो कोई ताला की जरूरत है: लेखन और एक अजगर शब्दकोश पढ़ने धागा सुरक्षित ही (सिवाय कर रहा है: writing while iterating is not allowed - लेकिन यह है कि एकल में अनुमति नहीं है धागा या तो)। स्मृति दृश्यता कुछ भाषाओं में volatile का उपयोग करके हासिल की जाएगी।

स्वाभाविक रूप से थ्रेड-सुरक्षित नहीं है "पढ़ने-संशोधित-लिखना" परिणामस्वरूप, जिसके परिणामस्वरूप दौड़ की स्थिति होती है। यदि Booleanका मान उसके पिछले मान पर निर्भर करता है, तो आपको लॉक का उपयोग करना होगा, क्योंकि अन्यथा थ्रेड ए पहले मान को पढ़ सकता है, फिर थ्रेड बी इसे बदल सकता है, और फिर ए इसे फिर से बदल देगा शुरू करने के लिए पुराना मूल्य।

0

आपको इस कार्रवाई के लिए शब्दकोश लॉक करने के लिए की जरूरत नहीं है क्योंकि यह कार्रवाई परमाणु है , और जीआईएल आपके लिए यह ख्याल रखता है। जब तक आपके पास रीड-चेंज-लिखित जैसे ऑपरेशन न हों, चिंता न करें।

संबंधित मुद्दे