如何知道需要多线程的作业何时完成?

时间:2012-06-05 04:26:06

标签: objective-c xcode4.3

我做的一件事是:

-(void)GrabbingProcess:(void (^)())block;
{
    self.OtherGrabbingIndicator +=1;
    block();
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_current_queue(), ^{
        self.OtherGrabbingIndicator -=1;
    });
}

每次我想在后台运行可能需要很长时间的事情时,我会做类似

的事情

[Grabclass grab] GrabbingProcess:^ { //做一些事情抓取数据等 }];

有许多这样的功能和许多这样的数据。例如,起初我会抓住所有的商家ID。然后我会在单独的线程中获取有关业务的所有详细信息。

我想知道所有这些线程完成并发布合适通知的时间。

我的解决方案的问题是,经过一段时间后,即使所有这些线程都已完成,self.OtherGrabbingIndicator在2或3左右徘徊的价值也经常不会下降。

不知何故有些自我。其他抓取指示符+ = 1; “泄露”并且与自我不匹配。其他抓取指示符 - = 1。我想知道这次泄密怎么会发生?

1 个答案:

答案 0 :(得分:1)

如果您想异步运行块,然后找出它们何时完成,那么相应的工具就是dispatch_group。您可以使用dispatch_group_async()将块分派到特定组和队列,该组将跟踪块何时完成。然后,您可以在组上同步等待以dispatch_group_wait()结束,或者在组完成dispatch_group_notify()时注册要调用的块。


您的解决方案无法正常工作的原因是您没有以线程安全的方式访问/改变计数器。这是导致问题的一系列微不足道的事件:

开始:self.OtherGrabbingIndicator为1
主题A :读取self.OtherGrabbingIndicator
线程B :读取self.OtherGrabbingIndicator
线程A :递增读取值并写回self.OtherGrabbingIndicator
线程B :递增读取值并写回self.OtherGrabbingIndicator
结束:self.OtherGrabbingIndicator是2

即使两个线程试图递增它,但只有一个“成功”并且你最终失去了另一个增量。这也可以在减量期间发生。如果你使用调度组,这个问题就会消失。


作为旁注,您绝不能使用dispatch_get_current_queue()。这是一个永远不应该在实际代码中使用的调试函数。主要原因是因为您不只是在一个队列上运行,而是同时在整个队列层次上运行,但此功能只能告诉您有关一个队列的信息。此外,您可能正在某人的私人队列中运行,您当然不应该自己调度。