2010-06-14 58 views
2

我正在尋找一些最佳方法來同步訪問C++中的對象的屬性的建議。該應用程序有一個內部緩存的對象有10個屬性。這些對象將被請求在集合中,然後可以修改它們的屬性並重新保存。他們可以通過2-4個線程在任何給定的時間進行訪問,但訪問並不激烈,所以我的選擇是:跨線程同步屬性的最佳方法

  1. 鎖定屬性爲每個對象使用臨界段存取。這意味着很多關鍵部分 - 每個對象一個。

  2. 當請求時返回對象的副本並具有更新函數,該函數鎖定單個關鍵部分以在適當時更新對象屬性。

我認爲選項2似乎是最有效的,但我只是想看看我是否錯過了隱藏的第三個選項,這將是更合適的。

感謝, Ĵ

+0

它聽起來不像「緩存」的傳統含義;請澄清 – Will 2010-06-14 09:14:18

+0

如果對象發生更改,更新情況會發生什麼?你在想一些CAS嗎? – 2010-06-14 09:26:36

+0

對不起,緩存我只是說對象被預先加載到內存中而不是從磁盤讀取。這在很大程度上與問題無關,所以請原諒錯誤的措詞。 – JWood 2010-06-14 10:18:26

回答

1

首先,我認爲你是在擔心錯誤的事情。您如何知道鎖定或複製會導致代碼中的瓶頸?關鍵部分相當輕量級,不會造成太多的開銷,或者至少不如您想象的那麼多。只需使用可用的最輕量級鎖定原語。如果您預計系統在多處理器硬件上運行,您甚至可以使用自旋鎖。其次,在性能(提示:更簡單的模型更容易理解,獲得正確和優化)之前,請不要擔心併發模型的簡單性。因此,如果您能負擔得起,請複製對象,這樣可以減輕處理TOCTOU競爭條件時的痛苦,以防您對對象集進行復雜變換,而這些變換取決於許多先前的值。

0

你不想要的關鍵部分,你想有一個互斥體。

對於每個對象都有一個單獨的互斥體是完全合理的。在讀取或寫入任何屬性之前鎖定互斥鎖,然後在完成後快速解鎖。

當沒有爭用時,互斥鎖的開銷非常低。當有很多爭論時,他們肯定會減慢你的程序速度。

+0

爲什麼是互斥體而不是臨界區? – 2010-06-14 09:05:27

+0

那種方式2個不同的線程不能更新同一個對象的2個不同的屬性。 – 2010-06-14 09:13:02

+0

Errm ...你想要一個可以肯定會減慢你的程序的互斥量? @Nick D:那種方式是哪個? – 2010-06-14 09:13:54

0

根據需要多長時間從對象讀取屬性(我猜它應該是相當瑣碎,像讀取int或std ::字符串),你可以使用spin-locks爲#3。它們是同步線程的最快方式。也許選項#4,僅適用於整數,根本不做鎖定,只使用atomic operations。也許,最有效的解決方案是將原子用於所有整數,對於簡單類型(POD和簡單對象,如std :: string)和每個對象互斥/ CS用於更復雜的任何屬性旋轉鎖。

只有一個分析器才能告訴你哪個是最好的選擇。