2013-04-09 41 views
0

以下代碼不是我的真實代碼。我問這個問題很簡單。
這是一個Web應用程序的服務器端代碼。
如何鎖定和修改每個單元'組'的字典安全性

我想要做的是鎖定組,當它被修改,但我不知道如何。
例如,屬於「GroupA」的用戶向服務器發佈了請求,並且我想將user_id添加到「GroupA」安全性字典中。
我想只鎖定'GroupA'包含的字典。我不想鎖定字典'組'包含。
因爲屬於'GroupB'的用戶決不會修改'GroupA'包含的字典
請給我建議。

# this dictionary is mutable which means new groups could be added anytime 
groups = {'GroupA': {}, 'GroupB': {}, 'GroupC': {}} 


def request_handler(request): 
    # Assuming these come from the user's http post 
    user_id = request.userid 
    user_group = request.user_group 

    group = groups[user_group] # a group contains user_id's dictionary 
    if user_id in group: 
     # the value of the key 'user_id' is the number of the user's post 
     group[user_id] = group[user_id] + 1 
    else: 
     group.append(user_id) 
     group[user_id] = 1 
+0

難道你不能只使用['threading.Lock()'](http://docs.python.org/2/library/threading。 html?highlight = lock#threading.Lock)來控制對每個組的子字典的訪問權限? – martineau 2013-04-09 01:22:52

+0

我不知道如何使用threading.Lock()生成的鎖對象,而不影響其他組的線程。 – Nigiri 2013-04-09 01:29:12

+1

在對子字典進行操作之前,您需要調用'lock.acquire()'並將其阻塞,直到其他已有控制權的線程調用lock.release()。查看關於[鎖定對象]的文檔(http://docs.python.org/2/library/threading.html?highlight=lock#lock-objects)。我認爲這樣做意味着每個子字典都需要自己的'Lock'對象。通過在訪問資源的縮進代碼塊之前使用'with'語句來獲取鎖定通常很方便,因爲它們也是合適的Python上下文管理器。 – martineau 2013-04-09 01:48:40

回答

1

您需要爲每個組單獨鎖定。例如: -

groups = {'GroupA': (Threading.Lock(), {}), 'GroupB': (Threading.Lock(), {})} 


def request_handler(request): 
    # Assuming these come from the user's http post 
    user_id = request.userid 
    user_group = request.user_group 

    glock, group = groups[user_group] 
    with glock: 
     group[user_id] = group.get(user_id, 0) + 1 

如果組也是動態的,您將需要爲groups鎖以及任何組添加或刪除之前必須獲得。

考慮其他方法:

  1. 亞型,字典和使用鎖適當地使用自己的映射類羣體。
  2. 有一個單線程負責讀取和更新組。讓其他線程通過一對Queues向其發送任務。 (現在你根本不需要鎖定)。
+0

你的示例代碼讓我非常清楚。謝謝! – Nigiri 2013-04-09 01:58:32