Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create a deadlock in Grand Central Dispatch?

Tags:

In Apple docs, it says:

Important: You should never call the dispatch_sync or dispatch_sync_f function from a task that is executing in the same queue that you are planning to pass to the function. This is particularly important for serial queues, which are guaranteed to deadlock, but should also be avoided for concurrent queues.

How do you write the code to do exactly this?

like image 605
BlackMouse Avatar asked Mar 13 '13 09:03

BlackMouse


People also ask

What is a deadlock Swift?

In short, a deadlock can occur when the system is waiting for a resource to free up while it's logically impossible for that resource to become available. You can think of this resource as almost anything.

What is deadlock GCD?

The word Deadlock refers to a situation in which a set of different threads sharing the same resource are waiting for each other release the resource to finish its tasks. When working with the GCD, if we do not fully understand the GCD's concepts, we may create a deadlock in our code.

How does Grand Central Dispatch work?

GCD is built on top of threads. Under the hood, it manages a shared thread pool. With GCD, you add blocks of code or work items to dispatch queues and GCD decides which thread to execute them on. As you structure your code, you'll find code blocks that can run simultaneously and some that should not.

What is Grand Central Dispatch iOS?

Grand Central Dispatch is used in iOS to introduce concurrency and parallelism in the iOS applications, so that multiple heavy tasks are performed in the background, resulting in the smooth experience of the application usage, as the main thread is unaffected by the heavy background tasks.


2 Answers

An intentional deadlock on a certain queue:

dispatch_queue_t queue = dispatch_queue_create("my.label", DISPATCH_QUEUE_SERIAL); dispatch_async(queue, ^{     dispatch_sync(queue, ^{         // outer block is waiting for this inner block to complete,         // inner block won't start before outer block finishes         // => deadlock     });      // this will never be reached });  

It's clear here that the outer and inner blocks are operating on the same queue. Most cases where this will occur is in places where it's less obvious what queue the caller of the dispatch_sync is operating on. This usually occurs in a (deeply) nested stack where you're executing code in some class that was originally launched on a certain queue, and by accident you call a dispatch_sync to the same queue.

like image 195
Joris Kluivers Avatar answered Oct 24 '22 14:10

Joris Kluivers


Simple code that creates deadlock:

dispatch_queue_t q = dispatch_queue_create("deadlock queue", DISPATCH_QUEUE_SERIAL);  NSLog(@"1"); dispatch_async(q, ^{     NSLog(@"2");     dispatch_sync(q, ^{         NSLog(@"3");     });     NSLog(@"4"); }); NSLog(@"5"); 

Log output:

1 5 2 

Here internal block is scheduled to be run on serial queue q but it cannot run until current block is finished, while current block, in turn, waits internal to finish as we called it synchronously.

like image 25
Vladimir Avatar answered Oct 24 '22 16:10

Vladimir