代码之家  ›  专栏  ›  技术社区  ›  Naresh aggregate1166877

在同一线程上以dispatch\u async运行两次的代码-objective c,ios

  •  0
  • Naresh aggregate1166877  · 技术社区  · 8 年前

    我有一个从网络接收数据时调用的方法。只是出于好奇,我保留了一个计数器来检查 相同的线程

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                NSLog(@"counterForAsync=%d",counterForAsync);
                ++counterForAsync;
                if (file)  {
                    [file seekToEndOfFile];
                }
                [file writeData:data];
    });
    

    我复制了控制台日志,并在崇高的观察它,并看到一些行被删除 重复的 .

    enter image description here

    enter image description here

    其他几行也是这样。 如果它运行了两次,那么它就坏了,因为我正在异步线程中执行文件操作。

    1 回复  |  直到 8 年前
        1
  •  2
  •   sj-r    8 年前

    有两种类型的调度队列。

    • 序列号
    • 同时发生的

    一个串行队列(像主队列一样)按您排队的顺序执行排队闭包,一次一个。

    但是,并发队列(如全局调度队列)同时执行闭包。(看一下 Apple documentation )

    在同一个计数器编号打印两次的情况下,第309次闭包在第308次闭包之前记录的计数器在计数器上加1。(你明白了吗?)

    因此,对于文件写入操作,您应该使用 serial queue 如下所示,如文档所述

    串行队列通常用于同步对特定资源的访问。

    dispatch_queue_t serialQueue = dispatch_queue_create("com.myqueue.filewrite", DISPATCH_QUEUE_SERIAL);
    
    dispatch_async(serialQueue, ^{
        NSLog(@"counterForAsync=%d",counterForAsync);
            ++counterForAsync;
            if (file)  {
                [file seekToEndOfFile];
            }
            [file writeData:data];
    });
    

    synchronization . 你应该 synchronize 你的代码 critical section (如添加计数器或写入文件)不能同时被两个以上的线程访问。