在iPhone上使用“mutex”和NSCondition共享内存

时间:2011-05-07 09:30:27

标签: iphone multithreading singleton semaphore shared-memory

我需要做什么:   为了避免全局变量,我有一个包含数组的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周围被阻止。

修改的 我尝试了不同的东西,但行为不是预期的:
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];
}
像这样,我正在解锁NSMutableArray,以便mainThread能够添加对象。

2 个答案:

答案 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  

希望可以帮助别人!