我正在创建一个阻塞队列,由大约 10 个工作线程同时访问。队列的基本实现是这样的:
-(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;
}
_mutex
一个在哪里NSCondition
。问题来自-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;
}
然后程序不会死锁,但是,当我重新获得锁时,另一个工作人员已经将我需要的对象出队。关于如何进行NSCondition
递归的任何想法?