2012-02-03 76 views
0

我正在創建一個阻塞隊列,由大約10個工作線程同時訪問。基本實現隊列是這樣的:NSCondition:遞歸鎖定?

-(void) enqueue:(__strong id)value 
{ 
    [_mutex lock]; 

    while ([self size] == _maxSize) { 
     [_mutex wait]; 
    } 

    [_queue enqueue:value]; 
    [_mutex signal]; 
    [_mutex unlock]; 
} 

-(id) dequeue 
{  
    [_mutex lock]; 

    while ([self isEmpty]) { 
     [_mutex wait]; 
    } 

    id value = [_queue dequeue]; 
    [_mutex broadcast]; 

    [_mutex unlock]; 
    return value; 
} 

_mutexNSCondition。這些問題都與-isEmpty-size方法:

-(int) size 
{ 
    @try { 
     [_mutex lock]; 

     return [_queue size]; 
    } 
    @finally { 
     [_mutex unlock];   
    } 
} 

-(BOOL) isEmpty 
{ 
    @try { 
     [_mutex lock]; 

     return [_queue isEmpty]; 
    } 
    @finally {  
     [_mutex unlock]; 
    } 
} 

因爲他們需要互斥鎖,以確保沒有數據損壞的很到位,它把程序陷入僵持,爲NSCondition不遞歸方式鎖定。但是,如果我改變我的實現以下幾點:

-(void) enqueue:(__strong id)value 
{ 
    while ([self size] == _maxSize) { 
     [_mutex lock]; 
     [_mutex wait]; 
     [_mutex unlock]; 
    } 

    [_mutex lock]; 
    [_queue enqueue:value]; 
    [_mutex signal]; 
    [_mutex unlock]; 
} 

-(id) dequeue 
{ 
    while ([self isEmpty]) { 
     [_mutex lock]; 
     [_mutex wait]; 
     [_mutex unlock]; 
    } 

    [_mutex lock]; // when I require the lock here, another thread has already dequeued the object 
    id value = [_queue dequeue]; 
    [_mutex broadcast]; 

    [_mutex unlock]; 
    return value; 
} 

然後程序不僵局,然而,我的時間重新AQUIRE鎖,另一名工人已經離隊,我需要已經是對象。任何想法如何使NSCondition遞歸?

回答

1

我一般採用以下模式:

-(int)primitiveSize 
{ 
    return [_queue size]; 
} 

方法在ObjC(從核心數據的命名傳統,推出)與primitive前綴表明,他們沒有任何副作用,無滑稽的生意,任何轉換,只是 - 給-ME-的價值。這樣,如果您已經獲得鎖而不封裝封裝,則可以使用primitiveSize

這比創建一個遞歸互斥體BTW快得多。

+0

我沒有想到這一點。感謝您在盒子外面思考! – 2012-02-03 15:54:20