【问题标题】:Shared memory with "mutex" and NSCondition on iPhoneiPhone 上与“mutex”和 NSCondition 共享内存
【发布时间】:2011-05-07 09:30:27
【问题描述】:

我需要做什么: 为了避免全局变量,我有一个包含数组的 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 能够添加对象。

【问题讨论】:

  • 嗨,只是一个观察,有第二个线程,其唯一目的是在主线程上调用选择器并等待它完成,这有点违背了拥有第二个线程的目的。跨度>
  • 你是绝对正确的。这就是我现在使用 NSOperation 的原因。我只是在主线程上运行异步 NSURLConnection 时遇到了问题。

标签: iphone multithreading singleton semaphore shared-memory


【解决方案1】:

第二个线程调用主线程上的一个方法,并在条件锁中等待直到完成该方法。这会导致死锁。 RequestLauncher 无法在第二个线程中调用?

【讨论】:

  • 好吧,我在主线程上调用这个方法,因为这是一个异步请求,它需要一个仅在主线程上可用的运行循环。我“等到完成”,以便一次只建立一个连接。除此以外,代码对您来说还不错吗?那我该怎么办?
【解决方案2】:

我终于得到了答案。
我更习惯于 C 多任务处理,在这里解释了混乱!

基本上,代码几乎没有问题。我认为信号正在做的是增加“信号量”的值,这样如果一个线程发出 5 次信号,另一个线程也会通过等待条件 5 次。 一点也不。

我在第一个线程中的代码很好(即)

[[sharedSingleton conditionLock] lock];  
[[sharedSingleton list] addObject:obj];  
[[sharedSingleton conditionLock] signal];  
[[sharedSingleton conditionLock] unlock];   

按照该页面中的 Apple 示例that page ,这就是我所做的

[[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  

希望对某人有所帮助!

【讨论】:

    猜你喜欢
    • 2014-10-08
    • 2018-03-21
    • 2015-05-12
    • 1970-01-01
    • 2021-12-04
    • 2016-06-22
    • 2021-05-26
    • 2012-06-18
    相关资源
    最近更新 更多