I have come across a very interesting problem related to queue dead lock in iOS. Any way to avoid this?
Consider this:
- Create a custom serial queue.
- Dispatch some task (#1) on this serial queue asynchronously.
- This async task (#1) on dispatches some task (#2) onto main queue sync.
- Main queue dispatches some task (#3) onto serial queue sync.
- Result - DeadLock
Below is the sample code for this.
- Since self.opQueue is a serial queue, task#3 will not start till task#1 completes.
- Since task#1 is calling main queue sync, so it will never complete till main queue completes task#2.
Since main queue is waiting for opQueue to finish task#3, and opQueue is waiting for main queue to finish task#2 there is a deadlock.
#import "ViewController.h" @interface ViewController () @property(nonatomic,strong) dispatch_queue_t opQueue; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; dispatch_queue_t queue = dispatch_queue_create("com.tarun.sqqueue", DISPATCH_QUEUE_SERIAL); self.opQueue = queue; [self performOperations]; } /// 1. Dispatch on serial queue async. /// 2. This async task on serial queue dispatchs some task onto /// main queue sync. /// 3. Main queue dispatched some task onto serial queue sync. /// 4. Result - DeadLock - (void)performOperations { /// task#1: Dispatch task on the serial Queue Asynchronously. /// So this is not blocking. dispatch_async(self.opQueue, ^{ for (int i = 1; i<=100; i++) { NSLog(@"%d. Async on Serial Queue from Main Queue.",i); } /// task#2: Dispatching task on main queue synchronously from serial /// queue.So this queue will wait till main queue executes this task.(Blocking) dispatch_sync(dispatch_get_main_queue(), ^{ for (int i = 1; i<=100; i++) { NSLog(@"%d. Sync on main queue from Serial Queue.",i); } }); }); /// task#3: Dispatching task on swrial queue synchronously from main /// queue.So main queue will wait till serial queue executes this task. (Blocking) dispatch_sync(self.opQueue, ^{ for (int i = 1; i<=100; i++) { NSLog(@"%d. Sync on Serial Queue From Main Queue.",i); } }); /// Since self.opQueue is a serial queue, task#3 will not start till task#1 completes. /// Since task#1 is calling main queue sync, /// so it will never complete till main queue completes task#2. /// Since main queue is waiting for opQueue to finish task#3, and opQueue is waiting for main queue to finish task#2 there is a deadlock. NSLog(@"Back to main queue"); } @end