2012-02-03 79 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