iOS多線程分析

進程

1.正在進行的一個過程或任務(wù),負責任務(wù)執(zhí)行的是cpu尚困。
2.每個進程之間是獨立的椎例,每個進程都運行在獨立的內(nèi)存空間內(nèi),并擁有獨立運行所需的全部資源印颤。

線程

1.程序運行時的最小單位您机,是進程的實際運作單位。
2.進程想要執(zhí)行任務(wù)必須至少有一個線程年局。在應(yīng)用程序啟動時际看,系統(tǒng)會默認開啟一個線程,即主線程矢否。

進程和線程的關(guān)系

1.線程在進程下進行
2.一個進程可以包含多個線程
3.同一個進程內(nèi)不同的線程間數(shù)據(jù)容易共享
4.進程是用內(nèi)存地址可以上鎖仲闽,即一個線程使用共享內(nèi)存時,其他線程必須等待其結(jié)束僵朗,才能使用赖欣。(互斥鎖)
5.進程使用的內(nèi)存地址也可以限定使用,即當前只允許2 人訪問验庙,第三人需要等待有人結(jié)束訪問后再進行訪問顶吮。(信號量)
6.一個程序有多個進程,一個進程可以有多個線程粪薛,但每個進程至少要有一個線程悴了。

多線程

1.多條線程并發(fā)執(zhí)行,cpu快速的在多條線程之間調(diào)度违寿。 如果cpu調(diào)度線程時間足夠的快湃交,就造成了多線程并發(fā)的假象。
2.如果線程非常多陨界,也會大量消耗cpu資源巡揍。
3.多線程可以提高程序的執(zhí)行效率,能適當提高資源的利用率菌瘪。
4.如果開啟大量的線程會占用內(nèi)存空間腮敌,降低程序性能阱当。

隊列

串行隊列

同一時間內(nèi),隊列中只能執(zhí)行一個任務(wù)糜工,當前任務(wù)結(jié)束后才能執(zhí)行下一個任務(wù)弊添。

并發(fā)隊列

同時允許多個任務(wù)并發(fā)執(zhí)行。

iOS中的多線程

GCD

1.獲取主線程

dispatch_queue_t main_queue = dispatch_get_main();

2.線程延時

/** 
DISPATCH_TIME_NOW : 現(xiàn)在
DISPATCH_TIME_FOREVER : 永遠超時
NSEC_PER_SEC : 秒  (1000,000,000 納秒 = 1秒) 可精確到納秒級捌木,eg. 0.1 *  NSEC_PER_SEC 是0.1 * 1000,000,000 = 100,000,000 納秒 = 0.1秒 以下算法雷同油坝。
NSEC_PER_MSEC : 毫秒 (1000,000 納秒  = 1 毫秒)可精確到毫秒級
USEC_PER_SEC : 秒   (1000000微秒 = 1秒) 可精確到微秒級
NSEC_PER_USEC : 微秒  (1000納秒 = 1 微秒) 可精確到納秒級
*/
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC), main_queue, ^{
    NSLog(@"哈哈");
})

3.只執(zhí)行一次,常用作單例模式

static dispatch_once_t once;
dispatch_once(&once, ^{
     // 只實例化一次
     personModel = [[self alloc] init];
 });

4.線程組刨裆,即等待一組任務(wù)完成后繼續(xù)執(zhí)行下一步澈圈,常被應(yīng)用在圖片上傳

    // 開啟全集并發(fā)線程,DISPATCH_QUEUE_PRIORITY_DEFAULT 是線程等級帆啃, 0 是flag瞬女,備用字段,通常設(shè)置0
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, queue, ^{
       // 進行操作1
    });
    dispatch_group_async(group, queue, ^{
       // 進行操作2
    });
    dispatch_group_async(group, queue, ^{
       // 進行操作3
    });
    
    dispatch_group_notify(group, queue, ^{
       // 操作1努潘。2诽偷。3 執(zhí)行完畢 進行 下一步操作
    });
    // 超時等待,即設(shè)置一個最長等待時常疯坤,超過時間后 調(diào)起 notify block
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

5.信號量报慕,設(shè)置最大并發(fā)線程數(shù),設(shè)置數(shù)大于1時順序不能保證

//創(chuàng)建信號量压怠, 2為設(shè)置最大并發(fā)線程
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(2);
    for (int i = 0; i < 5; i++) {
        // 創(chuàng)建異步線程
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            // 信號量的等待時長眠冈,這里設(shè)置為一直等待,當信號量小于0 時一直等待刑峡,如果大于1則進入且降低信號量即-1
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
            // 睡眠2秒
            sleep(2);
            // po 出當前線程洋闽, 顯示log
            NSLog(@"%@", [NSThread currentThread]);
            // 標記信號量 + 1
            dispatch_semaphore_signal(semaphore);
            
        });
    }
    
    for (int i = 0; i < 5; i++) {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
            sleep(2);
            NSLog(@"%@", [NSThread currentThread]);
            dispatch_semaphore_signal(semaphore);
            
        });
    }

NSOPeration

NSOperation是基于GCD的抽象基類。
NSOperation可以跨隊列設(shè)置依賴關(guān)系
NSOperation面向?qū)ο笸幻危С諯VO诫舅,可以檢測operation是否正在執(zhí)行,是否結(jié)束或者取消
NSOperation實體子類有兩個宫患,NSBlockOperation 和 NSInvocationOperation

    // 初始化 方法實例
    NSInvocationOperation *invoOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(haha:) object:nil];
    [invoOperation start];
    // 初始化 block塊 實例
    NSBlockOperation *blockOpertaion = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"ni hao ");
    }];
// 繼續(xù)添加線程
blockOperation add
    [blockOpertaion start];
    // 以下為 依賴關(guān)系
    // 獲取 主線程
    NSOperationQueue *main_Operation = [NSOperationQueue mainQueue];
    // 創(chuàng)建 各種線程
    NSOperation *person_a = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"我是 神秘人 A");
    }];
    NSOperation *person_b = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"我是 神秘人 B");
    }];
    NSOperation *person_c = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"我是 神秘人 C");
    }];
    // 添加依賴關(guān)系挑围, A以來 B和C 松申,相當于 A要在 B C 之后才能執(zhí)行任務(wù)
    [person_a addDependency:person_b];
    [person_a addDependency:person_c];
    
    //添加到 主線程中 查看順序
    [main_Operation addOperation:person_a];
    [main_Operation addOperation:person_b];
    [main_Operation addOperation:person_c];

NSThread

NSThread使用比較簡單垄懂,可以靜態(tài)獲取線程信息

 // 獲取主線程
    NSThread *thread = [NSThread mainThread];
    // 判斷是否開啟了多線程
    BOOL isOpenThread = [NSThread isMultiThreaded];
    // 獲取當前線程
    NSThread *currentThread = [NSThread currentThread];
    // 當前線程睡眠 時間(s) 10秒鐘
    [NSThread sleepForTimeInterval:10];
    //  睡眠到指定時間 , 以下為當前時間往后延10秒鐘
    [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:10]];
    // 退出當前線程 围来, 禁止在主線程使用
    //[NSThread exit];

    // 初始化線程對象  實例化對象
    /*
     qualityOfService 線程的優(yōu)先級
     NSQualityOfServiceUserInteractive 最高級別,用于UI交互皇帮,點擊事件卷哩,繪制圖形等
     NSQualityOfServiceUserInitiated = 次高級別,用于執(zhí)行立即返回的任務(wù)
     NSQualityOfServiceUtility 普通級別属拾,不需要立即返回的任務(wù)
     NSQualityOfServiceBackground 后臺級別将谊,完全不緊急的任務(wù)
     NSQualityOfServiceDefault 默認級別
     */
    NSLog(@"%@", [NSThread currentThread]);
    NSThread *asynThread = [[NSThread alloc] initWithTarget:self selector:@selector(hello) object:nil];
    // 設(shè)置 線程實例化對象的 優(yōu)先級別冷溶,默認為 默認級別
    asynThread.qualityOfService = NSQualityOfServiceDefault;
    // 開始線程
    [asynThread start];
    
    // 也可以快速創(chuàng)建線程
    [NSThread detachNewThreadSelector:@selector(hello) toTarget:self withObject:nil];
    __weak typeof(self) weakSelf = self;
    [NSThread detachNewThreadWithBlock:^{
        // po 出當前線程
        NSLog(@"%@", [NSThread currentThread]);
        // 回到主線程
        [weakSelf performSelectorOnMainThread:@selector(hello) withObject:nil waitUntilDone:NO];
    }];

    // 還有一些 創(chuàng)建線程的方法
    // 3 秒后執(zhí)行 hello 方法 , 在當前線程
    [self performSelector:@selector(hello) withObject:nil afterDelay:3];
    // 后臺異步執(zhí)行
    [self performSelectorInBackground:@selector(hello) withObject:nil];
    // 在主線程上執(zhí)行 hello 方法
    [self performSelectorOnMainThread:@selector(hello) withObject:nil waitUntilDone:NO];
    // 在 指定的 asynThread 線程上執(zhí)行 hello方法  *** 注意避免在子線程中執(zhí)行 ui交互
    [self performSelector:@selector(hello) onThread:asynThread withObject:nil waitUntilDone:NO];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末尊浓,一起剝皮案震驚了整個濱河市逞频,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌栋齿,老刑警劉巖苗胀,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異瓦堵,居然都是意外死亡基协,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門谷丸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來堡掏,“玉大人,你說我怎么就攤上這事刨疼。” “怎么了鹅龄?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵揩慕,是天一觀的道長。 經(jīng)常有香客問我扮休,道長迎卤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任玷坠,我火速辦了婚禮蜗搔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘八堡。我一直安慰自己樟凄,他們只是感情好,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布兄渺。 她就那樣靜靜地躺著缝龄,像睡著了一般。 火紅的嫁衣襯著肌膚如雪挂谍。 梳的紋絲不亂的頭發(fā)上叔壤,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機與錄音口叙,去河邊找鬼炼绘。 笑死,一個胖子當著我的面吹牛妄田,可吹牛的內(nèi)容都是我干的俺亮。 我是一名探鬼主播驮捍,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼铅辞!你這毒婦竟也來了厌漂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤斟珊,失蹤者是張志新(化名)和其女友劉穎苇倡,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體囤踩,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡旨椒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了堵漱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片综慎。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖勤庐,靈堂內(nèi)的尸體忽然破棺而出示惊,到底是詐尸還是另有隱情,我是刑警寧澤愉镰,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布米罚,位于F島的核電站,受9級特大地震影響丈探,放射性物質(zhì)發(fā)生泄漏录择。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一碗降、第九天 我趴在偏房一處隱蔽的房頂上張望隘竭。 院中可真熱鬧,春花似錦讼渊、人聲如沸动看。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽弧圆。三九已至,卻和暖如春笔咽,著一層夾襖步出監(jiān)牢的瞬間搔预,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工叶组, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留拯田,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓甩十,卻偏偏與公主長得像船庇,于是被迫代替她去往敵國和親吭产。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容