Search code examples
swiftgrand-central-dispatch

Swift dispatch queues async order of execution


Considering this trivial piece of code

DispatchQueue.global().async {
    print("2")
}

print("1")

we can say that output will be as following:

1
2

Are there any circumstances under which order of execution will be different (disregarding kind of used queue)? May they be forced to appear manually if any?


Solution

  • You said:

    we can say that output will be as following ...

    No, at best you can only say that the output will often/frequently be in that order, but is not guaranteed to be so.

    The code snippet is dispatching code asynchronously to a global, concurrent queue, which will run it on a separate worker thread, and, in the absence of any synchronization, you have a classic race condition between the current thread and that worker thread. You have no guarantee of the sequence of these print statements, though, in practice, you will frequently see 1 before 2.

    this is one of the common questions at tech interview; and for some reason interviewers expect conclusion that order of execution is constant here. So (as it was not aligned with my understanding) I decided to clarify.

    Your understanding is correct, that the sequence of these two print statements is definitely not guaranteed.

    Are there any circumstances under which order of execution will be different

    A couple of thoughts:

    1. By adjusting queue priorities, for example, you can change the likelihood that 1 will appear before 2. But, again, not guaranteed.

    2. There are a variety of mechanisms to guarantee the order.

      • You can use a serial queue ... I gather you didn’t want to consider using another/different queue, but it is generally the right solution, so any discussion on this topic would be incomplete without that scenario;
      • You can use dispatch group ... you can notify on the global queue when the current queue satisfies the group;
      • You can use dispatch semaphores ... semaphores are a classic answer to the question, but IMHO semaphores should used sparingly as it’s so easy to make mistakes ... plus blocking threads is never a good idea;
      • For the sake of completeness, we should mention that you really can use any synchronization mechanism, such as locks.