約 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
再帰を作成する方法について何か考えはありますか?