【问题标题】:Is the dispatch_after method being executed concurrently in this code?这段代码中是否同时执行了 dispatch_after 方法?
【发布时间】:2012-08-02 19:57:00
【问题描述】:
int total = 0;            // these are globals..
BOOL dispatchCalled = NO; //

-(void) callDispatch
{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_current_queue(), ^{
        dispatchCalled = YES;
        NSLog(@"Total, after 300ms, is %i", total);
    });
}

-(void)play // this is my "main" method..
{
    NSLog(@"app starts running");

    [self callDispatch];

    while(!dispatchCalled)
    {
        total++;
    }

    [self callDispatch];
 }

控制台:

   2012-08-02 20:36:05.357 MyProject[8245:1a07] app starts running
   2012-08-02 20:36:05.693 MyProject[8245:3d03] Total, after 300ms, is 11513522
   2012-08-02 20:36:05.993 MyProject[8245:3d03] Total, after 300ms, is 11513523

当 callDispatch 中包含的方法第一次执行时,while 循环有时间执行 11513522 次。此时,while 循环的条件设置为YES,while 循环不应再执行。但是,它会在确认由调度方法条件更新之前再执行一次。这是为什么呢?

是不是因为 callDispatch 中包含的方法会并发/并行 while循环执行,这就解释了为什么while循环需要多一个循环-循环确认更新的条件?

【问题讨论】:

  • dispatch_after 块内设置断点——当它到达那里时,调试器会告诉你它在哪个线程上。

标签: iphone objective-c ios concurrency timer


【解决方案1】:

是的,它正在同时运行。这意味着您的块可以在 while 循环期间的任何给定时刻执行,例如在通过条件之后,但在增加全局之前,或者在增加全局之后。如果您多次运行代码,您会注意到有时total 计数匹配,有时则不匹配。 (编辑:这意味着您的代码在并发运行时是“不确定的”。)

如果您尝试在串行队列中运行上述代码,则 while 循环会无限运行,并且不会打印任何总数。在串行队列中,您在 callDispatch 中安排的块确实会添加到队列中以供下一个调用,但鉴于无限循环永远不会退出,该队列中的任何其他内容都不会被调用。

Apple Doc 中的更多信息:GCD offers three different kinds of queues

【讨论】:

    【解决方案2】:

    鉴于您有效地锁定了主事件循环,那么正在执行块的队列不能是主队列。

    因此,您肯定有两个线程在运行,因此,无法真正保证在第一个块和第二个块执行之间可能经过多少时间。同样,如果 dispatch_get_current_queue() 碰巧检索到一个异步队列,你不能假设其中的任何块同时执行。

    或者,更坦率地说:您无法推理并发代码中的执行和调度模式;你不能“玩电脑”,只能想出一种情况下发生的近似值。

    【讨论】:

    • 这段代码的编写方式使得 while 循环不会立即确认新条件,因此它需要再循环一次。除了这个小缺陷之外,您是否建议此代码会导致更大的不准确性?并且为了避免这种危险,将每个方法运行在单独的线程(或队列..我仍然不确定区别..)中解决这个问题吗?
    猜你喜欢
    • 1970-01-01
    • 2012-07-25
    • 1970-01-01
    • 1970-01-01
    • 2011-03-10
    • 1970-01-01
    • 1970-01-01
    • 2012-01-26
    • 1970-01-01
    相关资源
    最近更新 更多