關於串行 並行 同步 異步

作者:Love@YR
鏈接:http://blog.csdn.net/jingqiu880905/article/details/51699710
請尊重原創,謝謝!

看了很多關於這類的文章,一直沒有總結。不總結的話就會一直糊里糊塗,以下描述都是自己理解的非官方語言,不一定嚴謹,可當作參考。

首先,進程可理解成一個可執行文件的執行過程。在ios app上的話我們可以理解爲我們的app的.ipa文件執行過程也即app運行過程。殺掉app進程就殺掉了這個app在系統裏運行所佔的內存。

線程:線程是進程的最小單位。一個進程裏至少有一個主線程。就是那個main thread。非常簡單的app可能只需要一個主線程即UI線程。當然大部分還是會有一些子線程的,比如如果你用了AFNetWorking,你的請求都是開闢了子線程。

關於串行,並行,同步,異步,我還是以下面代碼的方式做個說明。

首先button點擊事件運行在主線程裏,先是在主線程裏做了打印了一句話,然後創建了一個串行或者並行的隊列,之後連續創建了3個同步或者異步的block任務放入此隊列中,最後再在主線程裏打印一句話。

- (IBAction)serialSync:(id)sender {
  NSLog(@"start log in main thread"]);
    dispatch_queue_t myQueue = dispatch_queue_create("myQueue", NULL);
    for (NSInteger n = 0; n < 3; n++) {
        dispatch_sync(myQueue, ^{
            for (NSInteger i = 0; i < 500000000; i++) {
                if (i == 0) {
                    NSLog(@"串行同步任務%ld -> 開始%@",n,[NSThread currentThread]);
                }
                if (i == 499999999) {
                    NSLog(@"串行同步任務%ld -> 完成",(long)n);
                }
            }
        });
    }
    NSLog(@"阻塞我沒有?當前線程%@",[NSThread currentThread]);
}

- (IBAction)serialAsync:(id)sender {
    NSLog(@"start log in main thread"]);
    dispatch_queue_t myQueue = dispatch_queue_create("myQueue", NULL);//創建一個串行隊列
    for (NSInteger n = 0; n < 3; n++) {
        dispatch_async(myQueue, ^{
            for (NSInteger i = 0; i < 500000000; i++) {
                if (i == 0) {
                    NSLog(@"串行異步任務%ld -> 開始%@",n,[NSThread currentThread]);
                }
                if (i == 499999999) {
                    NSLog(@"串行異步任務%ld -> 完成",(long)n);
                }
            }
        });
    }
    NSLog(@"阻塞我沒有?當前線程%@",[NSThread currentThread]);
}

- (IBAction)concurrentSync:(id)sender {
   NSLog(@"start log in main thread"]);
    dispatch_queue_t myQueue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
    for (NSInteger n = 0; n < 3; n++) {
        dispatch_sync(myQueue, ^{
            for (NSInteger i = 0; i < 500000000; i++) {
                if (i == 0) {
                    NSLog(@"並行同步任務%ld -> 開始%@",(long)n,[NSThread currentThread]);
                }
                if (i == 499999999) {
                    NSLog(@"並行同步任務%ld -> 完成",(long)n);
                }
            }
        });
    }

    NSLog(@"阻塞我沒有?當前線程%@",[NSThread currentThread]);
}
- (IBAction)concurrentAsync:(id)sender {
    NSLog(@"start log in main thread"]);
    dispatch_queue_t myQueue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
    for (NSInteger n = 0; n < 3; n++) {
        dispatch_async(myQueue, ^{
            for (NSInteger i = 0; i < 500000000; i++) {
                if (i == 0) {
                    NSLog(@"並行異步任務%ld -> 開始%@",n,[NSThread currentThread]);
                }
                if (i == 499999999) {
                    NSLog(@"並行異步任務%ld -> 完成",(long)n);
                }
            }
        });
    }
    NSLog(@"阻塞我沒有?當前線程%@",[NSThread currentThread]);
}

最後的結果如圖:
這裏寫圖片描述

其中我把第一句打印和最後一句打印用玫紅色表示,它們都運行在當前線程。
方框表示隊列,3個block任務分別爲3種不同的顏色。

可以看出:
串行即上一個block任務執行完畢下一個任務才加入到隊列中。
並行即其中的任務同時加入到隊列中。

從運行結果來看
第一個圖只有一個主線程:
3個block都是同步即都阻塞當前線程,所以最後那句打印的任務就在3個block運行完之後。
3個block又是串行,所以一個一個運行

第二個圖有2個線程即一個主線程一個子線程:
3個block都是異步,沒有任務阻塞當前線程。所以最後那句打印是在第一句打印後就可以開始執行的。
3個block都是異步,異步會創建新的線程即至少有一個子線程。
3個block是串行,只有一個任務做完纔會加另一個任務入隊列,所以只需一個子線程。

第三個圖只有一個主線程:
3個block都是同步即都阻塞當前線程,所以最後那句打印的任務就在3個block運行完之後。
3個block是並行,同時被加入隊列中。
3個block都是同步,由於同步意味着等待,所以任務的執行表現爲順序執行,其實是一起加進去的但是等待的,跟串行的區別是串行是別的任務做完才把它加進隊列中。

第四個圖有多個線程:
3個block都是異步,沒有任務阻塞當前線程。所以最後那句打印是在第一句打印後就可以開始執行的。
3個block都是異步,異步會創建新的線程即至少有一個子線程。
3個block是並行,需創建多個子線程才能保證任務同時執行。

再看一張圖:其中第一個異步爲玫紅色,兩個同步分別以紫色黃色表示,兩個異步分別以綠色棕色表示,隊列後面的當前線程動作爲橘色。虛線代表等待。上面代表串行,下面是並行。

這裏寫圖片描述

由此圖可以看出:
同步block會阻塞當前線程,即會在當前線程中運行。(這裏的當前線程爲主線程所以會看到UI卡住)
異步block會開闢新的線程。

在串行隊列中,異步block任務用的是同一個子線程,因爲需要等待任務一個一個地執行,不需要多個線程。
在並行隊列中,異步block任務同時執行,系統爲其分配線程。圖中的例子因第一個異步操作在第二個開始前已經結束了,所以並不是多少個異步操作就創建多少線程,主要還是看需要。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章