gpt4 book ai didi

ios - NSCondition,如果调用信号时没有锁定怎么办?

转载 作者:搜寻专家 更新时间:2023-10-30 20:16:35 25 4
gpt4 key购买 nike

来自 this Apple's document about NSConditionNSCondition的用法应该是:

头部 1:

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

线程 2:

[cocoaCondition lock];
timeToDoWork++;
[cocoaCondition signal];
[cocoaCondition unlock];

并且在 the document of method signal in NSConditon :

You use this method to wake up one thread that is waiting on the condition. You may call this method multiple times to wake up multiple threads. If no threads are waiting on the condition, this method does nothing. To avoid race conditions, you should invoke this method only while the receiver is locked.

我的问题是:

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

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

最佳答案

当多个线程正在访问共享数据时,锁定失败是一个严重的问题。在 Apple 代码的示例中,如果线程 2 没有锁定条件对象,那么它可以在线程 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( )。然而,如果共享数据比这更复杂(并且它可能在任何非平凡的情况下),那么他们确实需要使用同步机制,例如条件锁。

关于ios - NSCondition,如果调用信号时没有锁定怎么办?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27976126/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com