進程:正在進行中的程式被稱為進程,負責程式運行的記憶體分配;每一個進程都有自己獨立的虛擬記憶體空間; 線程:線程是進程中一個獨立的執行路徑(控制單元);一個進程中至少包含一條線程,即主線程。 隊列:dispatch_queue_t,一種先進先出的數據結構,線程的創建和回收不需要程式員操作,由隊列負責。 ...
進程:正在進行中的程式被稱為進程,負責程式運行的記憶體分配;每一個進程都有自己獨立的虛擬記憶體空間;
線程:線程是進程中一個獨立的執行路徑(控制單元);一個進程中至少包含一條線程,即主線程。
隊列:dispatch_queue_t,一種先進先出的數據結構,線程的創建和回收不需要程式員操作,由隊列負責。
串列隊列:隊列中的任務只會順序執行(類似跑步)
dispatch_queue_t q = dispatch_queue_create(“....”, dispatch_queue_serial);
並行隊列:隊列中的任務通常會併發執行(類似賽跑)
dispatch_queue_t q = dispatch_queue_create("......", dispatch_queue_concurrent);
全局隊列:是系統開發的,直接拿過來(get)用就可以;與並行隊列類似,但調試時,無法確認操作所在隊列
dispatch_queue_t q = dispatch_get_global_queue(dispatch_queue_priority_default, 0);
主隊列:每一個應用程式對應唯一一個主隊列,直接get即可;在多線程開發中,使用主隊列更新UI
dispatch_queue_t q = dispatch_get_main_queue();
操作
dispatch_async 非同步操作,會併發執行,無法確定任務的執行順序;
dispatch_sync 同步操作,會依次順序執行,能夠決定任務的執行順序;
串列隊列同步:操作不會新建線程、操作順序執行;
串列隊列非同步:操作需要一個子線程,會新建線程、線程的創建和回收不需要程式員參與,操作順序執行,是最安全的選擇;
並行隊列同步:操作不會新建線程、操作順序執行;
並行隊列非同步:操作會新建多個線程(有多少任務,就開n個線程執行)、操作無序執行;隊列前如果有其他任務,會等待前面的任務完成之後再執行;場景:既不影響主線程,又不需要
順序執行的操作!
全局隊列非同步:操作會新建多個線程、操作無序執行,隊列前如果有其他任務,會等待前面的任務完成之後再執行;
全局隊列同步:操作不會新建線程、操作順序執行;
主隊列非同步:操作都應該在主線程上順序執行的,不存在非同步的;
主隊列同步:如果把主線程中的操作看成一個大的block,那麼除非主線程被用戶殺掉,否則永遠不會結束;主隊列中添加的同步操作永遠不會被執行,會死鎖;
不同隊列嵌套dispathch_sync(同步)任務的結果
// 1.全局隊列,都在主線程上執行,不會死鎖 dispatch_queue_priority_default
dispatch_queue_t q = dispatch_get_global_queue(dispatch_queue_priority_default, 0);
// 2.並行隊列,都在主線程上執行,不會死鎖 dispatch_queue_concurrent
dispatch_queue_t q = dispatch_queue_create("cn.itcast.gcddemo", dispatch_queue_concurrent);
// 3.串列隊列,會死鎖,但是會執行嵌套同步操作之前的代碼 dispatch_queue_serial
dispatch_queue_t q = dispatch_queue_create("cn.itcast.gcddemo", dispatch_queue_serial);
// 4.主隊列,直接死鎖 dispatch_get_main_queue();
dispatch_queue_t q = dispatch_get_main_queue();
dispatch_sync同步應用開發場景
阻塞並行隊列的執行,要求某一操作執行後再進行後續操作,如用戶登錄
確保塊代碼之外的局部變數確實被修改
dispatch_queue_t q = dispatch_queue_create("cn.itcast.gcddemo", dispatch_queue_concurrent);
__block bool login = no;
dispatch_sync(q, ^{
nslog(@"模擬耗時操作 %@", [nsthread currentthread]);
[nsthread sleepfortimeinterval:2.0f];
nslog(@"模擬耗時完成 %@", [nsthread currentthread]);
login = yes;
});
dispatch_async(q, ^{
nslog(@"登錄完成的處理 %@", [nsthread currentthread]);
});
ios三種多線程技術:
1.nsthread
(1)使用nsthread對象建立一個線程非常方便
(2)但是!要使用nsthread管理多個線程非常困難,不推薦使用
(3)技巧!使用[nsthread currentthread]跟蹤任務所線上程,適用於這三種技術
2.nsoperation/nsoperationqueue
(1)是使用gcd實現的一套objective-c的api
(2)是面向對象的線程技術
(3)提供了一些在gcd中不容易實現的特性,如:限制最大併發數量、操作之間的依賴關係
3.gcd —— grand central dispatch
(1)是基於c語言的底層api
(2)用block定義任務,使用起來非常靈活便捷
(3)提供了更多的控制能力以及操作隊列中所不能使用的底層函數
1---- 隊列和線程的區別:
隊列:是管理線程的,相當於線程池,能管理線程什麼時候執行。
隊列分為串列隊列和並行隊列:
串列隊列:隊列中的線程按順序執行(不會同時執行)
並行隊列:隊列中的線程會併發執行,可能會有一個疑問,隊列不是先進先出嗎,如果後面的任務執行完了,怎麼出去的了。這裡需要強調下,任務執行完畢了,不一定出隊列。只有前面的任務執行完了,才會出隊列。
2----- 主線程隊列和gcd創建的隊列也是有區別的。
主線程隊列和gcd創建的隊列是不同的。在gcd中創建的隊列優先順序沒有主隊列高,所以在gcd中的串列隊列開啟同步任務裡面沒有嵌套任務是不會阻塞主線程,只有一種可能導致死鎖,就是串列隊列里,嵌套開啟任務,有可能會導致死鎖。
主線程隊列中不能開啟同步,會阻塞主線程。只能開啟非同步任務,開啟非同步任務也不會開啟新的線程,只是降低非同步任務的優先順序,讓cpu空閑的時候才去調用。而同步任務,會搶占主線程的資源,會造成死鎖。
3----- 線程:裡面有非常多的任務(同步,非同步)
同步與非同步的區別:
同步任務優先順序高,線上程中有執行順序,不會開啟新的線程。
非同步任務優先順序低,線上程中執行沒有順序,看cpu閑不閑。在主隊列中不會開啟新的線程,其他隊列會開啟新的線程。
4----主線程隊列註意:
在主隊列開啟非同步任務,不會開啟新的線程而是依然在主線程中執行代碼塊中的代碼。為什麼不會阻塞線程?
> 主隊列開啟非同步任務,雖然不會開啟新的線程,但是他會把非同步任務降低優先順序,等閑著的時候,就會在主線程上執行非同步任務。
在主隊列開啟同步任務,為什麼會阻塞線程?
> 在主隊列開啟同步任務,因為主隊列是串列隊列,裡面的線程是有順序的,先執行完一個線程才執行下一個線程,而主隊列始終就只有一個主線程,主線程是不會執行完畢的,因為他是無限迴圈的,除非關閉應用開發程式。因此在主線程開啟一個同步任務,同步任務會想搶占執行的資源,而主線程任務一直在執行某些操作,不肯放手。兩個的優先順序都很高,最終導致死鎖,阻塞線程了。
參考:http://www.makaidong.com/博客園熱/32951.shtml