如果在同一队列中分派怎么办? [英] What happens if dispatch on same queue?

查看:46
本文介绍了如果在同一队列中分派怎么办?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在以下情况下,我想了解是否需要检查callbackQueue是否为当前队列.

I'd like to understand for below case if it's needed to check whether callbackQueue is current queue.

请帮助我清除这些情况,以了解如果当前队列是回调队列会发生什么情况

Please help me clear these scenarios, about what could happen if current queue is callback queue:

  1. callbackQueue是主要队列.
  2. callbackQueue是并发队列.
  3. callbackQueue是串行队列.
  1. callbackQueue is main queue.
  2. callbackQueue is concurrent queue.
  3. callbackQueue is serial queue.

- (void)fetchWithCallbackQueue:(dispatch_queue_t)callbackQueue
{
  dispatch_async(callbackQueue, ^{

  });
}

推荐答案

我强烈建议您观看这些视频.然后浏览我提供的示例,然后更改代码并尽可能地使用它们.花了3年的时间我才完全熟悉iOS多线程,所以花点时间:D

I highly recommend you to watch these videos. Then go through the examples I provided and then change the code and play around with them as much as you can. It took me 3 years to feel fully comfortable with iOS multi-threading so take your time :D

观看此RWDevCon视频的前3分钟,如果您愿意,还可以观看更多.

Watch the first 3 minutes of this RWDevCon video and more if you like.

还要观看 3:45 直到 6:15 .尽管我建议您完整观看此视频.

Also watch 3:45 until 6:15. Though I recommend you watch this video in its entirety.

总结一下我提到的这段时间中视频的观点:

To summarize the points the videos make in the duration I mentioned:

线程和并发性与队列和目标有关.队列.

threading and conccurrency is all about the source queue and destination. queue.

sync与async专门取决于源队列.

sync vs. async is specifically a matter of the source queue.

想想正在工作的高速公路的源队列和目标队列.

Think of source and destination queues of a highway where your work is being done.

如果您异步,那么就好比您派一辆汽车(必须运送东西)离开高速公路,然后继续让其他汽车在高速公路上行驶.

If you do async, then it's like you sending a car (has to deliver stuff) exiting the highway and then continue to let other cars drive in the highway.

如果您进行同步,那么就好像您在高速公路上派一辆汽车(必须运送东西),然后将高速公路上的所有其他汽车停下来,直到汽车运送了所有东西.

If you do sync, then it's like you sending a car (has to deliver stuff) exiting the highway and then halting all other cars on the highway until the car delivers all its stuff.

想像一辆汽车以代码块的形式发送东西,开始执行并结束执行.

Think of a car delivering stuff as a block of code, starting and finishing execution.

主队列发生的事情与串行队列发生的事情相同.它们都是串行队列.

What happens for main queue is identical to what happens for serial queue. They're both serial queues.

因此,如果您已经在主线程上并分派到主线程并进行异步分派,那么您分派的所有内容都会转到队列末尾

So if you're already on main thread and dispatch to main thread and dispatch asynchronously then, anything you dispatch will go to the end of the queue

告诉我我的意思:您认为这将以什么顺序打印?您可以在Playground中轻松对其进行测试:

To show you what I mean: In what order do you think this would print? You can easily test this in Playground:

DispatchQueue.main.async {
    print("1")
    print("2")
    print("3")
    DispatchQueue.main.async {
        DispatchQueue.main.async {
            print("4")
        }
        print("5")
        print("6")
        print("7")
    }
    print("8")
}

DispatchQueue.main.async {
    print("9")
    print("10")
}

它将打印:

1
2
3
8
9
10
5
6
7
4

为什么?

主要是因为每次您分发到main时,它将到达队列末尾.

It's mainly because every time you dispatch to main, it will go to the end of queue.

在您已经在主队列中时向主服务器调度是一个非常隐蔽的微妙原因,导致您在应用程序的用户交互中看到许多微小的延迟.

Dispatching to main while you're already on the main queue is very hidden subtle reason for many tiny delays that you see in an app's user-interaction.

如果使用 sync 调度到同一 serial 队列,会发生什么?

What happens if you dispatch to the same serial queue using sync?

死锁!请参见此处

如果使用 sync 调度到同一并发队列,则不会出现死锁.但是其他所有线程只会在您执行 sync 的那一刻等待.我已经在下面进行了讨论.

If you dispatch to the same concurrent queue using sync, then you won't have a deadlock. But every other thread would just wait the moment you do sync. I've discussed that below.

现在,如果您要调度到并发队列,那么如果您进行同步,则就像高速公路的示例一样,整个5车道的高速公路一直被阻塞,直到汽车交付为止一切.除非在执行 .barrier 排队,并试图解决读写问题

Now if you're trying to dispatch to a concurrent queue, then if you do sync, it's just like the example of the highway, where the entire 5 lane highway is blocked till the car delivers everything. But it's kinda useless to do sync on a concurrent queue, unless you're doing something like a .barrier queue and are trying to solve a read-write problem.

但是,仅查看在并发队列上进行同步会发生什么情况:

But to just see what happens if you do sync on a concurrent queue:

let queue = DispatchQueue(label: "aConcurrentQueue", attributes: .concurrent)

for i in 0...4 {
    if i == 3 {
        queue.sync {
            someOperation(iteration: UInt32(i))
        }
    } else {
        queue.async {
            someOperation(iteration: UInt32(i))
        }
    }
}

func someOperation(iteration: UInt32) {
    sleep(1)
    print("iteration", iteration)
}

将记录:

// '3' will ALWAYS be first, because it's chocking the entire queue. 
// The rest happen concurrently. And each time you run the app, the sequence of the rest would be different, because of the nature of concurrency. But likely 4 will be closer to being completed last and 0 would be closer to being finished sooner.

iteration 3     
iteration 0
iteration 2
iteration 1
iteration 4

如果您在并发队列上执行 async ,则假设您的并发线程数量有限,例如同时执行5个然后5个任务.只是每个给定的任务都将到达队列的末尾.这样做是为了记录日志.您可以有多个日志线程.一个线程记录位置事件,另一线程记录购买等.

If you do async on a concurrent queue, then assuming you have a limited number of concurrent threads, e.g. 5 then 5 tasks would get executed at once. Just that each given task is going to the end of the queue. It would make sense to do this for logging stuff. You can have multiple log threads. One thread logging location events, another logging purchases, etc.

一个很好的操场例子是:

A good playground example would be:

let queue = DispatchQueue(label: "serial", attributes: .concurrent)

func delay(seconds: UInt32 ) {
    queue.async {
        sleep(seconds)
        print(seconds)
    }
}

for i in (1...5).reversed() {
    delay(seconds: UInt32(i))
}

即使您先调度了5个,也可以打印

Even though you've dispatched the 5 first, this would print

1
2
3
4
5

这篇关于如果在同一队列中分派怎么办?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆