我需要做什么:
为了避免全局变量,我有一个包含数组的Singleton类。这个数组将由两个不同的线程访问:
- 1)第一个将是主线程,并且必须不时地将对象添加到此NSMutableArray中。
- 2)另一个线程正在循环(同时为TRUE)并尝试清空数组(当它包含某些内容时)
我的想法是(以及我到目前为止所做的):
在我的单例类中,我有我的NSMutableArray(list
)和NSCondition(conditionLock
)。
我的主要工作是:
[[sharedSingleton conditionLock] lock];
[[sharedSingleton list] addObject:obj];
[[sharedSingleton conditionLock] signal];
[[sharedSingleton conditionLock] unlock];
我想阻止对象,以便在我尝试将对象放入其中时它不会变空。 (共享内存保护)。一旦将对象放入数组中,我就会发出另一个线程的信号。如果我理解正确的话,这会增加一个反击,就像信号量一样吗?信号告诉另一个线程“有一个物体,继续”。
第二个主题是做什么的:
while (YES) {
[[sharedRequest conditionLock] lock];
[[sharedRequest conditionLock] wait];
RequestLauncher * req = [[RequestLauncher alloc] initWithGenericsObject:[[sharedRequest list] objectAtIndex:0]];
[req performSelectorOnMainThread:@selector(Launch)
withObject: nil
waitUntilDone:YES];
[[sharedRequest list] removeObjectAtIndex:0];
[[sharedRequest conditionLock] unlock];
}
所以我想我的问题是我锁定然后等待信号,但所有Apple示例都按顺序排列。 当我在主线程中添加一个对象时,此代码似乎有效。但是,当我想添加多个时,它会在Lock周围被阻止。
修改的
我尝试了不同的东西,但行为不是预期的:
像这样,我正在解锁NSMutableArray,以便mainThread能够添加对象。
while (YES) {
[[sharedRequest conditionLock] lock];
[[sharedRequest conditionLock] wait];
GenericsObject * obj = [[sharedRequest list] objectAtIndex:0];
[[sharedRequest list] removeObjectAtIndex:0];
[[sharedRequest conditionLock] unlock];
RequestLauncher * req = [[RequestLauncher alloc] initWithGenericsObject:obj];
[req performSelectorOnMainThread:@selector(Launch) withObject: nil waitUntilDone:YES];
}
答案 0 :(得分:1)
第二个线程在主线程上调用一个方法并等待,直到完成条件锁定中的方法。这会导致DEADLOCK。 RequestLauncher无法在第二个线程中调用吗?
答案 1 :(得分:1)
我终于得到了答案 我更习惯于C多任务处理,解释这里的混乱!
基本上,代码几乎是好的。我认为信号正在做的是增加“信号量”的值,这样如果一个线程发出5次信号,另一个线程也会通过等待条件5次。 完全没有。
我在第一个帖子中的代码很好(即)
[[sharedSingleton conditionLock] lock];
[[sharedSingleton list] addObject:obj];
[[sharedSingleton conditionLock] signal];
[[sharedSingleton conditionLock] unlock];
在该页that page 中以Apple为例,这就是我所做的
[[sharedRequest conditionLock] lock];
while ( ! ([[sharedRequest list] count] >0) ) {
[[sharedRequest conditionLock] wait];
}
GenericObjects * obj = [[sharedRequest list] objectAtIndex:0];
[[sharedRequest list] removeObjectAtIndex:0];
[[sharedRequest conditionLock] unlock];
RequestLauncher * req = [[RequestLauncher alloc] initWithGenericsObject:obj];
[[appDel queue] addOperation:req]; // appDel is an instance of the application delegate, and where queue is an instance of NSOperationQueue
希望可以帮助别人!