2009-08-26 129 views
1

我有兩個進程 - 一個用戶進程和一個根級別的LaunchDaemon。我希望這兩個進程都具有共享設置。我試過讓這個通過sqlite數據庫工作,但已遇到腐敗問題。我曾考慮過使用NSUserDefaults,但NSGlobalDomain似乎只對用戶是全球性的,我需要一個跨用戶持久域,NSUserDefaults似乎沒有提供。跨用戶和跨進程共享設置

我試過直接讀取和寫入一個XML文件,並且我可以通過多線程(通過簡單的NSLock)正常工作,但是當我嘗試將O_EXLOCK應用於該文件以阻止一個進程寫另一個文件時,它似乎不起作用。

CFPreferences似乎與NSUserDefaults有大部分相同的問題。有一個kCFPreferencesAnyUser常數,但文檔說,我只能使用,如果我有管理員權限(用戶進程沒有)。

所以我的問題是這樣的:

我怎樣纔能有效地實現跨流程,跨用戶的共享設置?

回答

2

最好的辦法可能是O_EXLOCK的方法,爲了方便起見,將其包裝到NSFileHandle中(-initWithFileDescriptor:)。事情是這樣的(未經檢驗,未編譯):

寫作:

int fd = open([path UTF8String], O_TRUNC|O_EXLOCK); 
if (fd >= 0) 
{ 
    NSFileHandle *fh = [[NSFileHandle alloc] initWithFileDescriptor:fd closeOnDealloc:YES]; 
    [fh writeData:xmlData]; // Creating xmlData left as exercise for the reader 
    [fh release]; 
} 
else // Error stuff 

閱讀:

int fd = open([path UTF8String], O_RDONLY|O_SHLOCK); 
if (fd >= 0) 
{ 
    NSFileHandle *fh = [[NSFileHandle alloc] initWithFileDescriptor:fd closeOnDealloc:YES]; 
    NSData *xmlData = [fh readDataToEndOfFile]; 
    [fh release]; 
} 
else // Error stuff 

當然這些都會阻塞,因此,你需要使用O_NONBLOCK或把它們放在一個非UI線程,所以你的GUI應用程序不beachball。

你用O_EXLOCK看到了什麼問題?在使用O_EXLOCKO_SHLOCK

1

注意只是讓你避免通話。 Mac OS X上只支持諮詢鎖,並且,作爲聯機幫助頁flock()筆記:

諮詢鎖允許協作進程對文件進行一貫作業,但不保證一致性(即進程可能仍然可以訪問文件,而無需使用諮詢鎖可能導致不一致)。

如果兩個應用程序在每次打開諮詢鎖定文件時都沒有選擇進入諮詢鎖定系統,則會遇到問題。

您還可以嘗試讓用戶進程通過使用RPC的守護進程進行默認調用。然後它將代表客戶端應用程序處理所有默認的寫作;默認讀數已經達到了任何用戶,當前主機/任何主機默認值。