多線程介紹


進程\線程

  • 進程

    1. 進程 是指在系統(tǒng)中正在運行的一個應(yīng)用程序。
    2. 每個進程之間是獨立的点把,每個進程均運行在其專用的且受保護的內(nèi)存空間內(nèi)橘荠。
  • 線程

    1. 1個進程由多個線程組成(1個進程至少要有1個線程)。
    2. 線程是進程的基本執(zhí)行單元郎逃,一個進程的所有任務(wù)都在線程中執(zhí)行哥童。

多線程

  • 多線程

    1. 1個進程中可以開啟多個線程,多個線程可以同時執(zhí)行不同的任務(wù)褒翰。
    2. 多線程可以提高程序的執(zhí)行效率贮懈。
  • 多線程的原理

    1. 對于單核CPU來說,同一時間优训,CPU只能處理1個線程朵你,只有1個線程正在執(zhí)行。
    2. 多線程同時執(zhí)行的本質(zhì):是CPU快速的在多個線程之間的切換揣非。
    3. CPU調(diào)度線程的時間足夠快抡医,就造成了多線程的“同時”執(zhí)行。
    4. 如果線程數(shù)非常多早敬,CPU會在n個線程之間切換魂拦,消耗大量的CPU資源毛仪,每個線程被調(diào)度的次數(shù)會降低,線程的執(zhí)行效率降低芯勘。
  • 多線程的優(yōu)點

    1. 適當(dāng)提高程序的執(zhí)行效率箱靴。
    2. 適當(dāng)提高資源的利用率(CPU、內(nèi)存)荷愕。
    3. 線程上的任務(wù)執(zhí)行完成后衡怀,線程會自動銷毀
  • 多線程的缺點

    1. 開啟線程需要占用一定的內(nèi)存空間(默認情況下安疗,每一個線程都占用512KB)抛杨,如果開啟大量的線程,會占用大量的內(nèi)存空間荐类,降低程序的性能怖现。
    2. 線程越多,CPU在調(diào)用線程上的開銷就越大玉罐。
    3. 程序設(shè)計更加復(fù)雜屈嗤,比如線程間的通信、多線程的數(shù)據(jù)共享吊输。
  • 主線程

    1. 一個程序運行后饶号,默認會開啟1個線程,稱為“主線程”“UI線程”季蚂。
    2. 主線程一般用來刷新UI界面茫船,處理UI事件
    3. 主線程使用注意:別將耗時的操作放到主線程中扭屁,因為耗時操作會卡住主線程算谈,嚴重影響UI的流暢度,給用戶一種卡的壞體驗料滥。

同步和異步

  • 同步執(zhí)行

    1. 寫程序的時候都是從上到下然眼,從左到右,代碼執(zhí)行順序也是從上到下從右到左幔欧。
    2. 1個線程執(zhí)行多個任務(wù),也是依次執(zhí)行a->b->c丽声。
    3. 1個線程同一時間執(zhí)行1個任務(wù)礁蔗。
  • 異步執(zhí)行

    1. 多個線程可以同時執(zhí)行多個任務(wù)。
    2. 多個線程執(zhí)行多個任務(wù)可以同時執(zhí)行a雁社,b浴井,c。
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
    // 異步執(zhí)行
    [self performSelectorInBackground:@selector(test) withObject:nil];
    NSLog(@"over");
}

// 演示耗時操作
- (void)test {
    for (int i = 0; i < 1000 ; i++) {
        // 操作椕鼓欤空間 速度特別快
        // int n = 10;
        // 操作堆空間磺浙,速度慢
        // NSString *str = [NSString stringWithFormat:@"abc %d",i];
        // io操作  input output
        NSLog(@"abc");
    }
}

iOS中多線程的實現(xiàn)方案

  • 技術(shù)方案

    1. pthread洪囤,C語言的一套通用的多線程API,適用于UNIX\Linux\Windows等系統(tǒng)撕氧,跨平臺\可移植瘤缩,使用難度大,線程生命周期需要程序員管理伦泥。
    2. NSThread剥啤,OC語言,使用更加面向?qū)ο蟛桓唵我子酶樱芍苯硬僮骶€程對象,線程生命周期需要程序員管理防楷。
    3. GCD牺丙,C語言,旨在替代NSThread等線程技術(shù)复局,充分利用設(shè)備的多核冲簿,線程生命周期自動管理。
    4. NSOperation肖揣,基于OC語言(底層是GCD)民假,比GCD多了一些更簡單實用的功能,使用更加面向?qū)ο罅牛€程生命周期自動管理羊异。
  • pthread的使用

    1. 使用pthread需要導(dǎo)入頭文件#import <pthread.h>
    2. 導(dǎo)入的頭文件是跨平臺的彤断,都是C語言的野舶。
    3. 通過intpthread_create()函數(shù)創(chuàng)建線程。
    4. 在ARC中宰衙,使用到和C語言對應(yīng)的數(shù)據(jù)類型平道,應(yīng)該使用__bridge橋接,在MRC中不需要橋接供炼。在OC中一屋,如果是ARC的話,編譯的時候會自動添加retain袋哼、release冀墨、autorelease,ARC只負責(zé)OC的代碼,不負責(zé)C的代碼,如果C語言的框架中篷就,出現(xiàn)create箩做、retain虫腋、copy骄酗,需要release,而橋接的目的就是解決這個問題悦冀。
int pthread_create(pthread_t * __restrict,
    const pthread_attr_t * __restrict,
    void *(*)(void *),
    void * __restrict);
// 參數(shù):
// 第1個參數(shù)為指向線程標示符的指針(線程編號的地址)
// 第2個參數(shù)用來設(shè)置線程屬性
// void *(*)(void *) 返回值 (函數(shù)指針)(參數(shù))
// void * 返回值類型趋翻,類似于OC中的id
// (*) 函數(shù)的指針
// (void *) 參數(shù)列表
// 第3個參數(shù)是線程調(diào)用函數(shù)指針
// 第4個參數(shù)是運行函數(shù)的參數(shù)

// 返回值:
// 返回0 線程創(chuàng)建成功 此時第1個參數(shù)是新線程的編號
// 非0 線程創(chuàng)建失敗 返回對應(yīng)錯誤碼
pthread的使用
  • NSThread
    1. NSThread線程的執(zhí)行是異步的。
    2. 面向?qū)ο蟮姆绞絼?chuàng)建子線程雏门。
// 通過NSThread開啟1個子線程的3種方式
- (instancetype)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;
+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;
- (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg;
NSThread的使用
  • 線程的狀態(tài)
    1. 當(dāng)啟動線程后嘿歌,線程的方法并沒有立即執(zhí)行,而是進入就緒狀態(tài)茁影,等待CPU的調(diào)用宙帝。
    2. 線程的狀態(tài)分為新生狀態(tài)、就緒狀態(tài)募闲、運行狀態(tài)步脓、死亡狀態(tài)、阻塞狀態(tài)浩螺。
    3. 終止線程前靴患,要釋放之前分配的內(nèi)存。如果是ARC要出,需要清理C語言框架創(chuàng)建的對象鸳君,否則會出現(xiàn)內(nèi)存泄露。
線程的狀態(tài)
  • 線程常用屬性
    1. 線程名稱:設(shè)置線程名稱可以當(dāng)線程執(zhí)行的方法內(nèi)部出現(xiàn)異常的時候記錄異常和當(dāng)前線程患蹂。
    2. 線程優(yōu)先級:內(nèi)核調(diào)度算法在決定該運行哪個線程時或颊,會把線程的優(yōu)先級作為考量因素,較高優(yōu)先級的線程會比較低優(yōu)先級的線程具有更多的運行機會传于。較高優(yōu)先級不保證你的線程具有執(zhí)行的時間囱挑,只是相比較低優(yōu)先級的線程,它更有可能被調(diào)度器選擇執(zhí)行而已沼溜。
線程的屬性

多線程訪問共享資源的問題

  • 互斥鎖(線程同步)
    1. 如果多個線程同時讀寫一個公共變量(屬性)平挑,可能會出現(xiàn)問題。
    2. 為解決上面的問題系草,在代碼中加入互斥鎖(線程同步)
      • 互斥鎖保證鎖內(nèi)的代碼同一時間通熄,只有一個線程能夠執(zhí)行鎖住的代碼塊。
      • 互斥鎖的參數(shù)必須是一個對象找都,任意一個對象都可以唇辨,但是不能是線程執(zhí)行方法中定義的對象,一般用self即可檐嚣。
      • 互斥鎖的原理:每一個對象(NSObject)內(nèi)部都有一個鎖(變量)助泽,當(dāng)有線程要進入@synchronized到代碼塊中會先檢查對象的鎖是打開還是關(guān)閉狀態(tài),默認鎖是打開狀態(tài)(1)嚎京,如果是線程執(zhí)行到代碼塊內(nèi)部會先上鎖(0)嗡贺。如果鎖被關(guān)閉,再有線程要執(zhí)行代碼塊就先等待鞍帝,直到鎖打開才可以進入诫睬。
      • 加鎖后程序執(zhí)行的效率比不加鎖的時候要低,因為線程要等待鎖帕涌,但是鎖保證了多個線程同時操作全局變量的安全性摄凡。

線程執(zhí)行到@synchronized
① 檢查鎖的狀態(tài) 如果是開鎖狀態(tài)(1)轉(zhuǎn)到② 如果上鎖(0)轉(zhuǎn)到⑤
② 上鎖(0)
③ 執(zhí)行代碼塊
④ 執(zhí)行完畢 開鎖(1)
⑤ 線程等待(就緒狀態(tài))

未使用互斥鎖 多線程同時訪問共享資源引起的問題

使用互斥鎖解決多線程訪問共享資源的問題
  • 原子屬性

    1. 屬性中的修飾符:
      • nonatomic:非原子屬性。
      • atomic:原子屬性(線程安全)蚓曼,針對多線程設(shè)計的亲澡,屬性的修飾符默認值就是atomic。保證同一時間只有一個線程能夠?qū)懭?但是同一時間多個線程都可以取值)纫版。atomic本身就是一把鎖(自旋鎖)床绪。單寫多讀:單個線程寫入,多個線程可以讀取其弊。
    2. 自旋鎖和互斥鎖:
      • 相同點:都能保證同一個時間只有一個線程能夠執(zhí)行鎖定范圍內(nèi)代碼癞己。
      • 不同點:①互斥鎖:如果發(fā)現(xiàn)其他線程正在執(zhí)行鎖定代碼,線程會進入休眠(就緒狀態(tài))梭伐,等其它線程時間片到打開鎖后痹雅,線程會被喚醒(執(zhí)行)。
      • 自旋鎖:如果發(fā)現(xiàn)有其它線程正在鎖定代碼糊识,線程會用死循環(huán)的方式绩社,一直等待鎖定的代碼執(zhí)行完成,自旋鎖更適合執(zhí)行不耗時的代碼技掏。
      • 無論什么鎖铃将,性能都會有損耗(用性能換取數(shù)據(jù)安全性)。
  • 線程安全

    1. 線程是不安全的哑梳,多個線程同時操作同一個全局變量劲阎。
    2. 線程安全:在多個線程進行讀寫操作時,仍然能夠保證數(shù)據(jù)的正確鸠真。
    3. UI線程(主線程):
      • 幾乎所有UIKit提供的類都不是線程安全的悯仙。
      • 所有更新UI的操作都在主線程上執(zhí)行。
      • Mutable線程是不安全的吠卷。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末锡垄,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子祭隔,更是在濱河造成了極大的恐慌货岭,老刑警劉巖路操,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異千贯,居然都是意外死亡屯仗,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進店門搔谴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來魁袜,“玉大人,你說我怎么就攤上這事敦第》宓” “怎么了?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵芜果,是天一觀的道長鞠呈。 經(jīng)常有香客問我,道長右钾,這世上最難降的妖魔是什么粟按? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮霹粥,結(jié)果婚禮上灭将,老公的妹妹穿的比我還像新娘。我一直安慰自己后控,他們只是感情好庙曙,可當(dāng)我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著浩淘,像睡著了一般捌朴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上张抄,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天砂蔽,我揣著相機與錄音,去河邊找鬼署惯。 笑死左驾,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的极谊。 我是一名探鬼主播诡右,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼轻猖!你這毒婦竟也來了帆吻?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤咙边,失蹤者是張志新(化名)和其女友劉穎猜煮,沒想到半個月后次员,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡王带,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年翠肘,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片辫秧。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖被丧,靈堂內(nèi)的尸體忽然破棺而出盟戏,到底是詐尸還是另有隱情,我是刑警寧澤甥桂,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布柿究,位于F島的核電站,受9級特大地震影響黄选,放射性物質(zhì)發(fā)生泄漏蝇摸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一办陷、第九天 我趴在偏房一處隱蔽的房頂上張望貌夕。 院中可真熱鬧,春花似錦民镜、人聲如沸啡专。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽们童。三九已至,卻和暖如春鲸鹦,著一層夾襖步出監(jiān)牢的瞬間慧库,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工馋嗜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留齐板,地道東北人。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓葛菇,卻偏偏與公主長得像覆积,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子熟呛,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,851評論 2 361

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

  • 又來到了一個老生常談的問題宽档,應(yīng)用層軟件開發(fā)的程序員要不要了解和深入學(xué)習(xí)操作系統(tǒng)呢? 今天就這個問題開始庵朝,來談?wù)劜?..
    tangsl閱讀 4,134評論 0 23
  • 寫在前面的話: 這篇博客是我從這里“轉(zhuǎn)載”的吗冤,為什么轉(zhuǎn)載兩個字加“”呢又厉?因為這絕不是簡單的復(fù)制粘貼,我花了五六個小...
    SmartSean閱讀 4,743評論 12 45
  • Object C中創(chuàng)建線程的方法是什么椎瘟?如果在主線程中執(zhí)行代碼覆致,方法是什么?如果想延時執(zhí)行代碼肺蔚、方法又是什么煌妈? 1...
    AlanGe閱讀 1,748評論 0 17
  • Java8張圖 11、字符串不變性 12宣羊、equals()方法璧诵、hashCode()方法的區(qū)別 13、...
    Miley_MOJIE閱讀 3,709評論 0 11
  • “哈嘍仇冯!美女之宿。什么時候發(fā)糖給我吃啊苛坚?”久未聯(lián)系的中學(xué)死黨打來電話比被。 “啊泼舱?這個嘛…淡定等缀,淡定啊〗筷迹總有該你吃的時候唄...
    姍姍讀書閱讀 319評論 0 0