2010-05-17 117 views
5

我正在使用下面的代碼進行線程安全訪問變量。線程安全get(訪問器方法)

int gnVariable; 

void getVariableValue(int *pnValue) 
{ 
    acquireLock(); //Acquires the protection mechanism 
    *pnValue = gnVariable; 
    releaseLock(); //Releasing the protection mechanism 
} 

我想我API的簽名更改爲更方便用戶

int getVariableValue(void); 

我應該如何重寫功能 - 使得API的用戶不必理會鎖定/解鎖細節?

+0

我不明白你的問題。您建議的API都不提供鎖定細節。 – zvrba 2010-05-17 06:24:21

+0

如果更改爲第二個版本 - int getVariable(void) - ,API的用戶將不得不手動釋放/解鎖信號量。如果你不這樣做Samuel和Naveen建議 – sonofdelphi 2010-05-17 07:51:01

回答

9

既然你給了C++一個選項,你可以包裝互斥鎖/解鎖。然後,您可以直接返回值:

class lock_wrapper 
{ 
public: 
    lock_wrapper() 
    { 
     acquireLock(); 
    } 
    ~lock_wrapper() 
    { 
     releaseLock(); 
    } 
}; 

int getVariableValue() 
{ 
    lock_wrapper lw; 
    return gnVariable; 
} 

這也會派上用場,如果你需要做一個鎖定/周圍的代碼,可以拋出異常解鎖。

+0

在C中做同樣的想法嗎? – sonofdelphi 2010-05-17 06:04:38

+1

我曾經爲此使用計數信號量。在一些實時操作系統中計算信號量支持原子操作的getValue()操作。 – sonofdelphi 2010-05-17 06:05:58

+0

@sonofdelphi - 對於C,你應該使用Naveen的答案。 – 2010-05-17 06:06:01

8

您返回本地變量的副本。喜歡的東西:

int getVariableValue(void) 
{ 
    int local= 0; 
    acquireLock(); 
    local = gnVariable; 
    releaseLock(); 
    return local; 
} 

作爲一個側面說明,最好是RAII原則鎖定,而不是acquireLockreleaseLock方法。

+0

本地副本似乎有點不雅。 :)沒有其他的去? – sonofdelphi 2010-05-17 06:07:06

+0

@sonofdelphi:@R Samuel Klatchko是一個更好的解決方案。我只是想演示如何使用本地副本來做到這一點。 – Naveen 2010-05-17 06:08:59

+2

@sonofdelphi:局部變量應該由一個體面的編譯器進行優化 - 它會將'gnVariable'直接複製到返回值位置。 – caf 2010-05-17 06:24:57