Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如果呼叫信号没有锁定怎么办?_Ios_Objective C_Multithreading_Nscondition - Fatal编程技术网

Ios 如果呼叫信号没有锁定怎么办?

Ios 如果呼叫信号没有锁定怎么办?,ios,objective-c,multithreading,nscondition,Ios,Objective C,Multithreading,Nscondition,在中,NSCondition的用法应为: Thead 1: [cocoaCondition lock]; while (timeToDoWork <= 0) [cocoaCondition wait]; timeToDoWork--; // Do real work here. [cocoaCondition unlock]; [cocoaCondition lock]; timeToDoWork++; [cocoaCondition signal]; [cocoaConditi

在中,
NSCondition
的用法应为:

Thead 1:

[cocoaCondition lock];
while (timeToDoWork <= 0)
    [cocoaCondition wait];
timeToDoWork--;
// Do real work here.
[cocoaCondition unlock];
[cocoaCondition lock];
timeToDoWork++;
[cocoaCondition signal];
[cocoaCondition unlock];
以及:

您可以使用此方法唤醒正在等待条件的一个线程。您可以多次调用此方法以唤醒多个线程。如果没有线程等待该条件,则此方法不执行任何操作为避免竞争条件,您应该仅在接收器锁定时调用此方法

我的问题是: 我不希望线程2在任何情况下都被阻塞,因此我删除了线程2中的
锁定
解锁
调用。也就是说,线程2可以放任意多的工作,线程1将一个接一个地完成工作,如果没有更多的工作,它将等待(阻塞)。这也是生产者-消费者模式,但生产者从未被封锁


但根据苹果的文件,这种方式是不正确的,那么在这种模式下可能会出现什么问题呢?谢谢。

当多个线程访问共享数据时,无法锁定是一个严重的问题。在Apple代码的示例中,如果线程2没有锁定condition对象,那么它可以在线程1递减的同时递增
timeToDoWork
。这可能导致其中一个操作的结果丢失。例如:

线程1读取当前值
timeToDoWork
,获取1
线程2读取当前值
timeToDoWork
,得到1
线程2计算递增的值(
timeToDoWork
+1),得到2
线程1计算递减值(
timeToDoWork
-1),得到0
线程2写入新值
timeToDoWork
,存储2
线程1写入新值
timeToDoWork
,存储0

timeToDoWork
从1开始,递增和递减,因此它应该以1结束,但实际上以0结束。通过重新安排步骤,结果可能是2步。大概,
timeToDoWork
的值代表了一些真实而重要的东西。搞错了可能会把程序搞砸


如果您的两个线程正在做一些简单的事情,比如递增和递减一个数字,那么它们可以通过使用原子操作函数(如
OSAtomicIncrement32Barrier()
OSAtomicDecrement32Barrier()
)在不锁定的情况下完成。但是,如果共享数据比这更复杂(在任何非平凡的情况下都可能如此),那么他们确实需要使用同步机制,如条件锁。

谢谢Ken。我正在研究的实际情况是生产者客户模式,我使用NSMutableArray来实现它。当一个线程向其添加对象时,另一个线程将对象取下。当没有对象时,使用者线程将等待。但我不希望生产者线程被阻止。有什么方法可以实现这一点吗?您必须同步对
NSMutableArray
的访问。当其他线程可能正在访问它时,对其进行变异是不安全的。同步访问的一种机制是将所有访问作为任务放在串行GCD队列中。推送可以是异步的。这将允许生产者继续使用GCD队列作为第二个线程安全的排序数据结构。然而,生产商无限期地领先于消费者又有什么意义呢?你最终需要它停下来等待消费者赶上,否则你将消耗内存和其他资源。是的,我明白了,非常感谢。就我的情况而言,它是一个消息发送者,用户可以在屏幕上连续点击或移动以生成许多消息,而另一个线程-消费者-则可以发送消息。因此,主线程(生产者)不能被阻止。您可以将生产者分派到异步串行队列中。这样就可以在不影响用户界面的情况下进行阻止