Difference Between Dispatchqueue Types in Swift

Difference between DispatchQueue types in swift

As I understand:

Queue is not Thread

Main and global queue may work in same thread

Dispatched: means put task in queue

If Global queue dispatched in Main queue as sync , the dispatched task will work on same thread of Main queue and dispatched task added to Global queue ,
And this task will freezing the thread

If Global queue dispatched in Main queue as async , the dispatched task will work on other thread of Main queue and dispatched task added to Global queue ,
And this task will not freezing the thread

If Main queue dispatched in Main queue as async , the dispatched task will work on same thread of Main queue

If Main queue dispatched in Main queue as sync will make exception because make deadlock

Dispatch.sync: put task in queue and wait it until finish

Dispatch.async: put task in queue and not wait it until finish (The task may work in same thread or in another thread)

  • If task dispatched on Global queue and this accord from Main thread
    then the task will added to Global queue , and new thread will be
    create and the task will start working immediately in the new thread

  • If task dispatched on Main queue and this accord from Main thread
    then the task will added to Main queue , and will not work
    immediately until older tasks in queue finish working (because Main
    queue is sequential )

What is the difference between these two Dispatch Queues?

There's a huge difference: the global queue is concurrent while your video queue is serial.

If you submit two blocks directly to the global queue, the system is allowed to run them concurrently.

If you submit two blocks to your video queue, the system must run them sequentially (not concurrently). The first block you submitted must return before the queue is allowed to call the second block. This means you can use your video queue as a serialization/locking mechanism to access state in a thread-safe way.

Other differences that I'm aware of:

  • In Xcode's debug navigator, the queues are labeled differently.

  • You can set the autorelease frequency of the video queue that you created.

  • If you set a quality-of-service class on the video queue when you create it, that QoS will override the QoS of the target queue.

  • You can suspend and resume dispatching on your video queue. I'm not sure if suspend and resume work on the global queue, but if they do, I'm sure suspending a global queue is a bad idea. You don't know what important tasks the system might be queuing on the global queues.

  • You can setSpecific values on your video queue, and then access them using getSpecific in blocks queued to the video queue. But getSpecific will not return those values in blocks queued directly to the global queue. This is most often used to detect when API calls are made on a particular queue, for thread-safety reasons.

What is the difference in approach to create DispatchQueue Swift3

The queue you create in your first example is your own custom serial queue. As the somewhat dated, yet still relevant, Concurrency Programming Guide says:

Serial queues (also known as private dispatch queues) execute one task at a time in the order in which they are added to the queue. The currently executing task runs on a distinct thread (which can vary from task to task) that is managed by the dispatch queue. Serial queues are often used to synchronize access to a specific resource.

You can create as many serial queues as you need, and each queue operates concurrently with respect to all other queues. In other words, if you create four serial queues, each queue executes only one task at a time but up to four tasks could still execute concurrently, one from each queue.

Whereas your latter examples are using simply retrieving system-provided global queues which are concurrent:

Concurrent queues (also known as a type of global dispatch queue) execute one or more tasks concurrently, but tasks are still started in the order in which they were added to the queue. The currently executing tasks run on distinct threads that are managed by the dispatch queue. The exact number of tasks executing at any given point is variable and depends on system conditions.

Now, you can nowadays create your own custom concurrent queue, but a global queue is simply a concurrent queue that was created for us.

So, what does this mean to you?

  • If you dispatch blocks to serial queue (your first example), only one block can run at any time. This makes it really useful for synchronizing memory access in multi-threaded apps, but can be used in any environment where you need a background queue, but you want dispatched blocks to be run serially (i.e. sequentially) with respect to other blocks on that queue.

  • The global queues that you are using in your latter examples are concurrent queues. This means that if you dispatch four separate tasks to this global queue, those blocks may run concurrently with respect to each other). This is ideal where you really want not only background execution, but don't care if these blocks also run at the same time as other dispatched blocks, too.

  • In your latter examples, where you're accessing a global queue, recognize that because those are system-provided, you have some modest limitations on your interaction with these queues, namely:

    • You cannot suspend global queues;

    • You cannot use barriers on global queues;
       

    But, with that notwithstanding, if you are just looking for an simple way of dispatching blocks to run in the background (and you don't care if those dispatched blocks run at the same time as each other), then global queues are incredibly simple and efficient way to do that.


By the way, the difference between your second example (for which I assume you intended let backgroundQueue = DispatchQueue.global()) and the third example, is merely that in your third example, you assigned the explicit quality of service (qos), whereas in your second example, you're using the default qos. FWIW, it's generally advisable to specify a qos, so that the OS can prioritize threads contending for limited system resources accordingly.

Difference between DispatchQueue.main.async and DispatchQueue.main.sync

When you use async it lets the calling queue move on without waiting until the dispatched block is executed. On the contrary sync will make the calling queue stop and wait until the work you've dispatched in the block is done. Therefore sync is subject to lead to deadlocks. Try running DispatchQueue.main.sync from the main queue and the app will freeze because the calling queue will wait until the dispatched block is over but it won't be even able to start (because the queue is stopped and waiting)

When to use sync? When you need to wait for something done on a DIFFERENT queue and only then continue working on your current queue

Example of using sync:

On a serial queue you could use sync as a mutex in order to make sure that only one thread is able to perform the protected piece of code at the same time.

Difference Between DispatchQueue.sync vs DispatchQueue.async

Sync will stop the current thread until it has finished the task you are assigning to it.

Async will continue with the current thread and will execute the task in parallel or after the current thread.

Why it has unexpected behaviour?

That is because loadView() expects to have a UIView assigned to the view property after it has been executed, which you are doing it with async, which will be executed after loadView finishes.

The exception might be because you are not assigning a UIView on time or because you are handling the UI in your private Queue. UI should always be handled in the main thread.

Your variable que is a private queue, and because you didn't specify otherwise it is pointing to a background thread.

Editing your code like this might help you:

import UIKit
import PlaygroundSupport

class MyViewController : UIViewController {
override func loadView() {
let view = UIView()
view.backgroundColor = .white

let que = DispatchQueue.init(label: "testing")
// Executed 3 times
que.sync {
for i in 0...10 {
print(i)
}
}
// Giving me NSException
DispatchQueue.main.async {
let label = UILabel()
label.frame = CGRect(x: 150, y: 200, width: 200, height: 20)
label.text = "Hello World!"
label.textColor = .black

view.addSubview(label)

print("Label Added to Text View")
}
self.view = view
}
}

// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()

What's the difference between Swift's Dispatchqueue and Flutter's Future?

DispatchQueue is for parallelization your tasks. It works according to the first in first out principle, means the first tasks will be done first etc.
A Future sounds for me like a "delayed" task, means your task will be done in the future but not in the background like in a DispatchQueue.
Some good information for DispatchQueue are here Appropriately-using-dispatchqueue-main :-)

main.async vs main.sync() vs global().async in Swift3 GCD

In simple term i come to conclusion that -

  • Queue- There are 3 Types of Queue i.e. 1 Main Queue, 4 Global Queue and Any No. of Custom Queues.
  • Threads- One is Main Thread and other background threads which system
    provides to us.

DispatchQueue.main.async

-It means performing task in main queue with using of background thread (w/o blocking of UI) and when task finish it automatic Updated to UI because its already in Main Queue.

DispatchQueue.global().async along with global().sync

It means performing task in Global Queue with using of background thread and when task finish, than global().sync use bring the work from globalQueue to mainQueue which update to UI.

Reason of My App Crash

I was trying to bring the completed task to MainQueue by using(main.sync), but it was already on MainQueue because i hadnt switched the Queue, and this create DeadLock (MainQueue waiting for itself), causes my app crash



Related Topics



Leave a reply



Submit