所以我遇到了竞争状态,我有一些解决问题的方法。我是新手,很明显,我的意见和研究是有限的。如果用户从服务器收到某些消息,我会发生大量的异步调用。因此,由于我的物体的依赖性,我的设计很差。
假设我有一个名为
的函数adduser:(NSString s){
does some asynchronize activity
}
Messageuser:(NSString s)
{
Does some more asychronize activity
}
如果用户收到消息告诉它添加用户“Ryan”。他不会创建一个主题并继续查找Ryan并存储他。但是,如果用户使应用程序处于挂起模式,并且在等待接收的缓冲消息中存在addUser请求和MessageUser请求,则会发生竞争条件,因为完成Adduser所需的时间比完成MessageUser所需的时间长。因此,如果调用messageUser,并且(在我们的示例中)“Ryan”尚未完全添加,则会引发错误。
这个问题的可能解决方案是什么。我查看了锁和信号量,我想要做的是,当MessageUser收到一个调用时,检查以确保当前没有线程处理addUser。如果没有,请继续。否则等待,而不是在完成后继续。
答案 0 :(得分:1)
这取决于首先发布消息的方式以及异步响应事件的内容。
如果操作具有依赖性(排序要求),那么背景串行队列可能是合适的吗?这是确保按顺序处理消息的简单方法。
如果异步操作采用完成块,那么您可以让完成块发出下一个要执行的操作的请求,尽管您可能不会提前知道。
如果您需要以更一般的方式解决此问题,那么您需要某种系统来跟踪先决条件,以便您可以跳过尚未满足其先决条件的工作项。这可能意味着您自己的后台线程监视等待任务列表并接收所有任务完成的通知,以便它可以扫描等待该完成的项目并发布它们。
虽然看起来真的很复杂......我怀疑你并没有真正拥有如此强大的异步并行处理要求,而更简单的设计也同样有效。鉴于您从服务器接收消息的情况,我认为串行队列将是最佳选择。然后,您可以按照服务器发送的顺序处理消息并保持简单。
//do this once at app startup
dispatch_queue_t queue = dispatch_queue_create("com.example.myapp", NULL);
//handle server responses
dispatch_async(queue, ^{
//handle server message here, one at a time
});
实际上,根据您连接到服务器的方式,您可以将整个连接处理移动到后台队列,并通过来自UI的消息与其进行通信,并通过调度到dispatch_get_main_queue()来更新UI。这将是UI线程。