zoukankan      html  css  js  c++  java
  • 关于dispatch_sync死锁问题

    首先。我们来看下以下一个样例:
    代码:(串行队列里同步线程嵌套)
        NSLog(@"haha");
        dispatch_queue_t queue = dispatch_queue_create("test", nil);
        dispatch_sync(queue, ^ {
            NSLog(@"xxoo0");
            dispatch_sync(queue, ^ {
                NSLog(@"xxoo1");
            });
            NSLog(@"xxoo2");
        });
    执行结果:

    2014-08-25 14:30:24.440 test[4424:60b] haha
    2014-08-25 14:30:24.441 test[4424:60b] xxoo0

    在test串行队列中,有两个同步线程嵌套导致第二个同步线程执行不了,产生了死锁。
    原因是:在串行队列中,第二个同步线程要运行。必须等待第一个同步线程运行完毕后才可进行。可是第一个同步线程要运行完又得等待第二个同步线程运行完,由于第二个同步线程嵌套在第一个同步线程里,这就造成了两个同步线程互相等待,即死锁。
    特别强调:是在串行队列里!


        dispatch_queue_t queue = dispatch_queue_create("test", nil);
    这行代码中,第二个參数为nil值,相当与值为DISPATCH_QUEUE_SERIAL,即为串行的。

    假设把值改成DISPATCH_QUEUE_CONCURRENT。即为并行的,就不会导致两个同步线程死锁。或者使用dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)也行,由于dispatch_get_global_queue是并行队列。

    ok,我们来看第二个样例:

    代码:(主线程里的同步线程)

        NSLog(@"haha");
        dispatch_sync(dispatch_get_main_queue(), ^ {
            NSLog(@"xxoo");
        });
    执行结果:

    2014-08-25 15:01:58.922 test[4797:60b] haha

    结果还是死锁,这个样例事实上和第一个样例是类似的。主线程事实上就是在一个串行队列里的,我们写的这个同步线程就相当与第一个样例的第二个嵌套的同步线程。由于这个同步线程是在主线程里写的,就相当于嵌套在主线程里的。

    所以,对于
    dispatch_sync(queue, ^{});
    这行代码的意义能够概括为: 会堵塞当前线程等待串行queue中的全部任务运行完毕后再向下运行。

  • 相关阅读:
    Zabbix-Agent在主动模式启动服务后,提示no active checks on server [139.219.xx.xx:10051]: host [139.219.xx.xx] not found
    Linux中Sed的用法
    服务器监控软件有哪些?
    Linux和Windows中查看端口占用情况
    Window10中创建目录连接点
    C#中使用RabbitMQ收发队列消息
    ExtJs4.2中Tab选项卡的右击关闭其它和关闭当前功能不准确的解决方法
    Redis中取得所有Key、过期时间配置与获取、Key过期通知。
    使用Phantomjs和ChromeDriver添加Cookies的方法
    FasterRcnn训练数据集参数配置
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/7259785.html
Copyright © 2011-2022 走看看