当应用程序转换到后台时,我偶尔会遇到与并发线程上未正确完成的任务有关的崩溃。
所以我有 3 个线程:
场景如下:
在 applicationDidEnterBackground:
处理程序(肯定在 thread A
上执行)中,一个长时间运行的任务在 thread B
上开始以完成所有正在进行的操作(保存应用程序状态、关闭套接字等)。在这个任务中,我需要等到一个套接字正确完成它在 thread C
上的工作,然后才能继续这个长时间运行的任务。
以下是简化代码:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Some synchronous task.
[stateManager saveState];
// Here I need to wait until the socket finishes its task.
...
// Continuing of the long-running task.
...
}
完成此任务的可接受方式是什么。如果我这样做可以吗?
while (socket.isConnected)
{
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
// Continuing of the long-running task.
或者我当前的架构可能有问题,我需要使用 NSOperation
以某种方式序列化异步任务?
更新:问题已通过使用dispatch_semaphore
得到解决APIs正如@Rob Napier 所建议的那样。
首先,不要将这些视为线程,如果您使用 NSThread
或 performSelectorInBackground:
(或者更糟糕的是 pthreads)创建线程,请不要不要那样做。使用 GCD。 GCD 创建队列。队列顺序 block ,最终确实在线程上运行,但线程是一个实现细节,队列到线程没有 1:1 的映射。见 Migrating Away from Threads更多讨论。
对于如何等待其他操作的问题,您可能想要的工具是 dispatch_semaphore
。您创建信号量并将其交给两个操作。然后当你想等待某事时调用 dispatch_semaphore_wait
,当你想表明某事已经发生时调用 dispatch_sempahore_signal
。见 Using Dispatch Semaphores to Regulate the Use of Finite Resources更多示例代码。在这种情况下,“有限资源”是“套接字”。您想等到另一部分完成使用它并将其返回到池中。
即使您使用手动线程,信号量也可以工作,但我不能强调您不应该进行手动线程。你所有的并发都应该通过 GCD 来管理。这是 iOS 中整体并发管理的重要工具。
关于ios - 等待来自并发线程的事件的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33503885/
欢迎光临 OStack程序员社区-中国程序员成长平台 (https://ostack.cn/) | Powered by Discuz! X3.4 |