GCD之死锁体会
1.先看下幾句代碼
dispatch_queue_t serialqueue=dispatch_queue_create("serialqueue", DISPATCH_QUEUE_SERIAL);//串行線程隊列dispatch_sync(serialqueue, ^{NSLog(@"1");});dispatch_sync(dispatch_get_main_queue(), ^{NSLog(@"2");});2.前面博文寫了GCD之死鎖http://www.cnblogs.com/cuiyw/p/4369041.html寫了這樣一句:防死鎖秘籍:不要在串行隊列放dispatch_sync、dispatch_apply,這幾天一直想著這句話,今天看用戶自定義線程隊列時,看到串行線程隊列,所以就想著驗證著句話是否正確,以為像上面那樣寫,兩個都會死鎖,運行了下發現并不像想象當中的那樣。第一個能夠輸出,這讓我大吃一驚,以為這句話難道不正確是錯誤的?有看了下同步異步,并敲代碼體會了一下,發現是自己理解錯誤。
3.dispatch_sync、dispatch_apply這些都有體現同步。同步是阻塞當前線程,把參數中的block語句添加到參數中的線程隊列中執行,待執行完畢后,返回阻塞的地方繼續執行。
比如上面的兩個同步:
第一個:當前運行的是主線程隊列,mian queue,運行到dispatch_sync 時,主線程掛起,開始將block添加到自定義的串行線程隊列中,待執行完畢后返回到當前主線程隊列main queue。所以并不會產生死鎖。
第二個:當前主線程執行到第二個同步時,阻塞,開始將block添加到主線程隊列中,此時主線程隊列等待block執行,而block這邊等待主線程隊列執行完,這樣就產生了死鎖。
4.再看如下代碼:
dispatch_sync(queue,^{dispatch_async(dispatch_get_main_queue(), ^{NSLog(@"1");});});dispatch_sync(queue,^{dispatch_sync(dispatch_get_main_queue(), ^{NSLog(@"2");});});?上面兩部分代碼第一個不會死鎖,而第二個會死鎖。
個人分析理解,不一定正確。
第一個:主線程是串口線程隊列,執行到sync的時候阻塞主線程隊列,將block添加到全局線程隊列中,全局線程隊列開啟一個線程,以異步的方式將最里面的block添加到主線程串口隊列中,并返回,此時可以返回到原來阻塞的位置。
第二個:主線程執行到sync的時候阻塞主線程隊列,將block添加到全局線程隊列中,采用同步阻塞全局線程隊列將最里面的block添加到主線程隊列中,而此時主線程隊列阻塞等待block的返回,而block則等待主線程隊列執行完畢添加到主線程隊列中,這樣就死鎖了。
?
總結
- 上一篇: oracle创建表空间脚本
- 下一篇: 场景切换的效果