線程乌妙、進(jìn)程
1.iOS中的多線程操作、多線程方式建钥?
2.多線程的優(yōu)點(diǎn)和缺點(diǎn)分別是什么?
答:優(yōu)點(diǎn):1虐沥、將耗時(shí)較長(zhǎng)的操作(網(wǎng)絡(luò)請(qǐng)求熊经、圖片下載、音頻下載欲险、數(shù)據(jù)庫(kù)訪問等)放在子線程中執(zhí)行镐依,可以防止主線程的卡死;2天试、可以發(fā)揮多核處理的優(yōu)勢(shì)槐壳,提升cpu的使用率。
缺點(diǎn):1喜每、每開辟一個(gè)子線程就消耗一定的資源务唐;2雳攘、會(huì)造成代碼的可讀性變差;3枫笛、如果出現(xiàn)多個(gè)線程同時(shí)訪問一個(gè)資源吨灭,會(huì)出現(xiàn)資源爭(zhēng)奪的情況
3.2.NSOperationQueue中有一個(gè)屬性叫maxConcurrentCount即最大并發(fā)數(shù)。這里所謂的最大并發(fā)數(shù)指的是什么含義刑巧?
答:這里的最大并發(fā)數(shù)指得是在隊(duì)列中同時(shí)執(zhí)行的任務(wù)的個(gè)數(shù)喧兄。有很多人會(huì)認(rèn)為是所分配的線程的個(gè)數(shù)。其實(shí)不是的啊楚。因?yàn)榫€程的個(gè)數(shù)的多少取決于系統(tǒng)吠冤,系統(tǒng)會(huì)分配合適的線程數(shù)量來保證這些任務(wù)并發(fā)執(zhí)行的,作為程序員我們是沒辦法控制的
4.在項(xiàng)目中什么時(shí)候選擇使用GCD恭理,什么時(shí)候選擇使用NSOperation拯辙?
答:無論是GCD還是NSOperation其實(shí)都是多線程的一種實(shí)現(xiàn)形式。嚴(yán)格的說NSOperation和線程并沒有必然聯(lián)系蚯斯,更不是多線程薄风,NSOperation只是操作,封裝了target和action或者Block拍嵌,在主線程中執(zhí)行Operation遭赂,Operation就會(huì)運(yùn)行在主線程中,在子線程中執(zhí)行Operation横辆,Operation就運(yùn)行在子線程中撇他。它只有和NSOperationQueue聯(lián)合使用的時(shí)候,才能發(fā)揮出價(jià)值狈蚤。NSOperationQueue是Operation的管理者困肩,它首先是一個(gè)隊(duì)列,先來的任務(wù)先開始執(zhí)行脆侮,后來的任務(wù)后開始執(zhí)行锌畸,這些任務(wù)的執(zhí)行是并發(fā)的,NSOperationQueue負(fù)責(zé)為任務(wù)開辟線程以及關(guān)閉線程靖避,有點(diǎn)類似于cell重用潭枣,用有限的線程執(zhí)行任意數(shù)量的任務(wù),同時(shí)可以設(shè)置最大并發(fā)數(shù)幻捏,控制程序的性能盆犁,不至于全部任務(wù)一起執(zhí)行。GCD出現(xiàn)比NSOperationQueue要晚篡九,是一套基于C函數(shù)的API谐岁,由于是C函數(shù),所以性能比較高,使用靈活伊佃,安全窜司,當(dāng)然功能也強(qiáng)大。但是相對(duì)于GCD來講锭魔,NSOperationQueue對(duì)線程做了封裝例证,使用比較簡(jiǎn)單,尤其是不用管理線程的開啟和關(guān)閉迷捧。個(gè)人認(rèn)為织咧,如果僅僅是想要實(shí)現(xiàn)異步執(zhí)行任務(wù),首選GCD漠秋,如果要管理多個(gè)異步任務(wù)笙蒙,NSoperationQueue比較方便。如果要做更復(fù)雜的處理庆锦,比如前5個(gè)任務(wù)并發(fā)捅位,5個(gè)任務(wù)執(zhí)行完之后,需要串行執(zhí)行3個(gè)任務(wù)搂抒,之后再并發(fā)執(zhí)行若干任務(wù)艇搀,就需要使用GCD了∏缶В總的來說焰雕,特別簡(jiǎn)單的和非常復(fù)雜的多線程任務(wù)GCD比較適合,介于二者之間的用NSOperationQueue比較合適芳杏。
5.寫出在多線程情況下的一個(gè)單例矩屁。
答:一般情況下,在開發(fā)中我們所寫的單例都是偽單例爵赵。即只是保證了在調(diào)用某一方法時(shí)吝秕,所產(chǎn)生的對(duì)象只有一個(gè)法牲,但是沒有考慮其他的影響其引用計(jì)數(shù)的方法驾胆。例如retain碍论、copy等项滑。為了保證線程安全,單例的寫法如下所示:
方法一:
static AccountManager *sharedAccountManagerInstance = nil;
+ (AccountManager *)sharedManager{
@synchronized (self){
if (sharedAccountManagerInstance == nil) {
sharedAccountManagerInstance = [[AccountManager alloc] init];
}
}
return sharedAccountManagerInstance;
}
方法二:
static AccountManager *sharedAccountManagerInstance = nil;
+ (AccountManager *)sharedManager
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedAccountManagerInstance = [[AccountManager alloc] init];
});
return sharedAccountManagerInstance;
}
4克锣、NSThread中的Runloop的作用拢切,如何使用虚循?
每個(gè)線程(NSThread)對(duì)象中內(nèi)部都有一個(gè)run loop(NSRunLoop)對(duì)象用來循環(huán)處理輸入事件如捅,處理的事件包括兩類,一是來自Input sources的異步事件调煎,一是來自Timer sources的同步事件;
run Loop在處理輸入事件時(shí)會(huì)產(chǎn)生通知镜遣,可以通過Core Foundation向線程中添加run-loop observers來監(jiān)聽特定事件,以在監(jiān)聽的事件發(fā)生時(shí)做附加的處理工作。 主線程的Run Loop會(huì)在App運(yùn)行時(shí)自動(dòng)運(yùn)行,子線程中需要手動(dòng)運(yùn)行悲关。
Run Loop就是一個(gè)處理事件源的循環(huán)谎僻,你可以控制這個(gè)Run Loop運(yùn)行多久,如果當(dāng)前沒有事件發(fā)生寓辱,Run Loop會(huì)讓這個(gè)線程進(jìn)入睡眠狀態(tài)(避免再浪費(fèi)CPU時(shí)間)艘绍,如果有事件發(fā)生,Run Loop就處理這個(gè)事件秫筏。
如果子線程進(jìn)入一個(gè)循環(huán)需要不斷處理一些事件诱鞠,那么設(shè)置一個(gè)Run Loop是最好的處理方式,如果需要Timer这敬,那么Run Loop就是必須的航夺。
開發(fā)中遇到的需要使用Run Loop的情況有:
需要使用Port或者自定義Input Source與其他線程進(jìn)行通訊。
子線程中使用了定時(shí)器
使用任何performSelector*****到子線程中運(yùn)行方法
使用子線程去執(zhí)行周期性任務(wù)
NSURLConnection在子線程中發(fā)起異步請(qǐng)求
10)OC中創(chuàng)建線程的方法是什么崔涂?如果在主線程中執(zhí)行代碼阳掐,方法是什么
線程創(chuàng)建有三種方法:使用NSThread創(chuàng)建、使用GCD的dispatch冷蚂、使用子類化的NSOperation,然后將其加入NSOperationQueue;在主線程執(zhí)行代碼,方法是performSelectorOnMainThread,如果想延時(shí)執(zhí)行代碼可以用performSelector:onThread:withObject:waitUntilDone:
11)線程和進(jìn)程的區(qū)別和聯(lián)系
進(jìn)程和線程都是由操作系統(tǒng)所體會(huì)的程序運(yùn)行的基本單元缭保,系統(tǒng)利用該基本單元實(shí)現(xiàn)系統(tǒng)對(duì)應(yīng)用的并發(fā)性。
進(jìn)程和線程的主要差別在于它們是不同的操作系統(tǒng)資源管理方式蝙茶。進(jìn)程有獨(dú)立的地址空間艺骂,一個(gè)進(jìn)程崩潰后,在保護(hù)模式下不會(huì)對(duì)其它進(jìn)程產(chǎn)生影響尸闸,而線程只是一個(gè)進(jìn)程中的不同執(zhí)行路徑彻亲。線程有自己的堆棧和局部變量,但線程之間沒有單獨(dú)的地址空間吮廉,一個(gè)線程死掉就等于整個(gè)進(jìn)程死掉苞尝,所以多進(jìn)程的程序要比多線程的程序健壯,但在進(jìn)程切換時(shí)宦芦,耗費(fèi)資源較大宙址,效率要差一些。但對(duì)于一些要求同時(shí)進(jìn)行并且又要共享某些變量的并發(fā)操作调卑,只能用線程抡砂,不能用進(jìn)程
9.在項(xiàng)目什么時(shí)候選擇使用GCD,什么時(shí)候選擇NSOperation恬涧?
gcd是基于c的底層api注益,NSOperation屬于object-c類。
相對(duì)于gcd:
1溯捆,NSOperation擁有更多的函數(shù)可用丑搔,具體查看api。
2,在NSOperationQueue中啤月,可以建立各個(gè)NSOperation之間的依賴關(guān)系煮仇。
3,有kvo谎仲,可以監(jiān)測(cè)operation是否正在執(zhí)行(isExecuted)浙垫、是否結(jié)束(isFinished),是否取消(isCanceld)郑诺。
4夹姥,NSOperationQueue可以方便的管理并發(fā)、NSOperation之間的優(yōu)先級(jí)间景。
gcd主要與block結(jié)合使用佃声。
項(xiàng)目中使用NSOperation的優(yōu)點(diǎn)是NSOperation是對(duì)線程的高度抽象,在項(xiàng)目中使用它倘要,會(huì)使項(xiàng)目的程序結(jié)構(gòu)更好圾亏,子類化NSOperation的設(shè)計(jì)思路,是具有面向?qū)ο蟮膬?yōu)點(diǎn)(復(fù)用封拧、封裝)志鹃,使得實(shí)現(xiàn)是多線程支持,而接口簡(jiǎn)單泽西,建議在復(fù)雜項(xiàng)目中使用曹铃。
項(xiàng)目中使用GCD的優(yōu)點(diǎn)是GCD本身非常簡(jiǎn)單、易用捧杉,對(duì)于不復(fù)雜的多線程操作陕见,會(huì)節(jié)省代碼量,而Block參數(shù)的使用味抖,會(huì)是代碼更為易讀评甜,建議在簡(jiǎn)單項(xiàng)目中使用。
7.線程注意事項(xiàng)
關(guān)于多線程的詳細(xì)介紹
http://mobile.51cto.com/iphone-403490.htm
1仔涩、線程的堆棧大小
iPhone設(shè)備上的應(yīng)用程序開發(fā)也是屬于嵌入式設(shè)備的開發(fā)忍坷,同樣需要注意嵌入式設(shè)備開發(fā)時(shí)的幾點(diǎn)問題,比如資源上限熔脂,處理器速度等佩研。
iPhone中的線程應(yīng)用并不是無節(jié)制的,官方給出的資料顯示iPhone OS下的主線程的堆棧大小是1M霞揉,第二個(gè)線程開始都是512KB旬薯。并且該值不能通過編譯器開關(guān)或線程API函數(shù)來更改。
2适秩、Autorelease
如果你什么都不考慮袍暴,在線程函數(shù)內(nèi)調(diào)用autorelease些侍,會(huì)出現(xiàn)錯(cuò)誤
3、子線程中描畫窗口
多線程編程中普遍遵循一個(gè)原則政模,就是一切與UI相關(guān)的操作都有主線程做,子線程只負(fù)責(zé)事務(wù)蚂会,數(shù)據(jù)方面的處理淋样。那么如果想在子線程中更新UI時(shí)怎么做呢?如果是在windows下胁住,你會(huì)PostMessage一個(gè)描畫更新的消息趁猴,在iPhone中,需要使用performSelectorOnMainThread委托主線程處理彪见。
總結(jié):
多線程能適當(dāng)提高程序的執(zhí)行效率儡司,能適當(dāng)提高資源利用率(CPU、內(nèi)存利用率)余指,但是開啟線程需要占用一定的內(nèi)存空間(默認(rèn)情況下捕犬,主線程占用1M,子線程占用512KB)酵镜,如果開啟大量的線程碉碉,會(huì)占用大量的內(nèi)存空間,降低程序的性能淮韭,而且線程越多垢粮,CPU在調(diào)度線程上的開銷就越大,使用多線程程序設(shè)計(jì)更加復(fù)雜:比如線程之間的通信靠粪、多線程的數(shù)據(jù)共享
一個(gè)iOS程序運(yùn)行后蜡吧,默認(rèn)會(huì)開啟1條線程,稱為“主線程”或“UI線程”
主線程的使用注意:別將比較耗時(shí)的操作放到主線程中占键。耗時(shí)操作會(huì)卡住主線程昔善,嚴(yán)重影響UI的流暢度,給用戶一種“卡”的壞體驗(yàn)
25.線程是什么捞慌?進(jìn)程是什么耀鸦?二者有什么區(qū)別和聯(lián)系? (UI第二十二講 多線程編程)
線程是CPU獨(dú)立運(yùn)行和獨(dú)立調(diào)度的基本單位(可以理解為一個(gè)進(jìn)程中執(zhí)行的代碼片段)啸澡,進(jìn)程是資源分配的基本單位(進(jìn)程是一塊包含了某些資源的內(nèi)存區(qū)域)袖订。進(jìn)程是線程的容器,真正完成代碼執(zhí)行的是線程嗅虏,而進(jìn)程則作為線程的執(zhí)行環(huán)境洛姑。一個(gè)程序至少包含一個(gè)進(jìn)程,一個(gè)進(jìn)程至少包含一個(gè)線程皮服,一個(gè)進(jìn)程中的多個(gè)線程共享當(dāng)前進(jìn)程所擁有的資源楞艾。
26.談?wù)勀銓?duì)多線程開發(fā)的理解参咙?ios中有幾種實(shí)現(xiàn)多線程的方法?(UI第二十二講 多線程編程)
好處:
①硫眯、使用線程可以把程序中占據(jù)時(shí)間長(zhǎng)的任務(wù)放到后臺(tái)去處理蕴侧,如圖片、視頻的下載
②两入、發(fā)揮多核處理器的優(yōu)勢(shì)净宵,并發(fā)執(zhí)行讓系統(tǒng)運(yùn)行的更快、更流暢裹纳,用戶體驗(yàn)更好
缺點(diǎn):
①择葡、大量的線程降低代碼的可讀性,
②剃氧、更多的線程需要更多的內(nèi)存空間
③敏储、當(dāng)多個(gè)線程對(duì)同一個(gè)資源出現(xiàn)爭(zhēng)奪的時(shí)候要注意線程安全的問題。
iOS有三種多線程編程的技術(shù):
①朋鞍、NSThread(兩種創(chuàng)建方式)
[NSThread detachNewThreadSelector:@selector(doSomething:) toTarget:self withObject:nil];
NSThread *myThread = [[NSThread alloc] initWithTarget:self selector:@selector(doSomething:) object:nil];
[myThread start];
②已添、NSOperationQueue
NSOperationQueue *oprationQueue = [[NSOperationQueue alloc] init];
oprationQueue addOperationWithBlock:^{
//這個(gè)block語句塊在子線程中執(zhí)行
}
http://alloc.sinaapp.com/wp/?p=237
③、Grand Central Dispatch (GCD)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//耗時(shí)的操作
dispatch_async(dispatch_get_main_queue(), ^{
//更新界面
});
});
http://blog.csdn.net/totogo2010/article/details/8016129
PS:不顯示的創(chuàng)建線程的方法:
用NSObject的類方法performSelectorInBackground:withObject:
創(chuàng)建一個(gè)線程:
[Obj performSelectorInBackground:@selector(doSomething) withObject:nil];
27.線程同步和異步的區(qū)別番舆?IOS中如何實(shí)現(xiàn)多線程的同步酝碳?
同步:一個(gè)線程要等待上一個(gè)線程執(zhí)行完之后才能執(zhí)行當(dāng)前的線程,生活中的例子(上廁所)恨狈。
異步:同時(shí)去做兩件或者多件事疏哗。比如邊聽歌邊看報(bào)。
.runloop和線程有什么關(guān)系禾怠?
總的說來返奉,Run loop,正如其名吗氏,loop表示某種循環(huán)芽偏,和run放在一起就表示一直在運(yùn)行著的循環(huán)。實(shí)際上弦讽,run loop和線程是緊密相連的污尉,可以這樣說run loop是為了線程而生,沒有線程往产,它就沒有存在的必要被碗。Run loops是線程的基礎(chǔ)架構(gòu)部分,Cocoa和CoreFundation都提供了run loop對(duì)象方便配置和管理線程的run loop(以下都以Cocoa為例)仿村。每個(gè)線程锐朴,包括程序的主線程(main thread)都有與之相應(yīng)的run loop對(duì)象。
runloop和線程的關(guān)系:主線程的run loop默認(rèn)是啟動(dòng)的蔼囊。iOS的應(yīng)用程序里面焚志,程序啟動(dòng)后會(huì)有一個(gè)如下的main()函數(shù)
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
重點(diǎn)是UIApplicationMain()函數(shù)衣迷,這個(gè)方法會(huì)為main thread設(shè)置一個(gè)NSRunLoop對(duì)象,這就解釋了:為什么我們的應(yīng)用可以在無人操作的時(shí)候休息酱酬,需要讓它干活的時(shí)候又能立馬響應(yīng)壶谒。
對(duì)其它線程來說,run loop默認(rèn)是沒有啟動(dòng)的膳沽,如果你需要更多的線程交互則可以手動(dòng)配置和啟動(dòng)佃迄,如果線程只是去執(zhí)行一個(gè)長(zhǎng)時(shí)間的已確定的任務(wù)則不需要。
在任何一個(gè)Cocoa程序的線程中贵少,都可以通過以下代碼來獲取到當(dāng)前線程的run loop。
NSRunLoop *runloop = [NSRunLoop currentRunLoop];
51. GCD的隊(duì)列(dispatch_queue_t)分哪兩種類型堆缘?
串行隊(duì)列Serial Dispatch Queue
并行隊(duì)列Concurrent Dispatch Queue
77.你參與的APP滔灶,是如何處理多個(gè)服務(wù)的同步發(fā)起的?
使用iOS線程技術(shù)吼肥,創(chuàng)建并行隊(duì)列來分別執(zhí)行不同的任務(wù)录平。將不同的任務(wù)加入到子隊(duì)列當(dāng)中,任務(wù)執(zhí)行后回到主線程當(dāng)中刷新UI界面缀皱。
APP界面一般都是根據(jù)產(chǎn)品需求和UI效果圖來完成的斗这,但是我們?yōu)榱颂岣叽a的復(fù)用性,會(huì)將視圖的實(shí)現(xiàn)進(jìn)行封裝啤斗,然后在控制器當(dāng)中進(jìn)行加載調(diào)用88.NSOperationQueue有哪些使用方式表箭?
一種在iOS中執(zhí)行并發(fā)操作的方法,是使用NSOperation和NSOperationQueue類钮莲。在本教程中免钻,你將學(xué)習(xí)如何使用它們!你會(huì)先創(chuàng)建一款不使用多線程的app崔拥,這樣它會(huì)變得響應(yīng)非常遲鈍极舔。然后改進(jìn)程序,添加上并行操作–并且希望–可以提供一個(gè)交互響應(yīng)更好的界面給用戶链瓦!
另一種處理操作之間的依賴關(guān)系拆魏,如果操作直接有依賴關(guān)系,比如第二個(gè)操作必須等第一個(gè)操作結(jié)束后再執(zhí)行慈俯〔橙校控制線程池中的線程數(shù),具體參考http://blog.sina.com.cn/s/blog_45e2b66c0100ztz7.html
89.NSThread中的Runloop的作用肥卡,如何使用溪掀?
有些情況下,我們還是在運(yùn)行一些長(zhǎng)線任務(wù)或者復(fù)雜任務(wù)的時(shí)候需要用比較原始的NSThread步鉴。這就需要為NSThread創(chuàng)建一個(gè)run loop.
1 NSThread *thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(playerThread: ) object:nil];
2[thread start];
3//如果要利用NSOperation揪胃,原理類似璃哟。只需要加入到queue里面去就好了。喊递。queue會(huì)在合適的時(shí)機(jī)調(diào)用方法随闪,下面代碼作為參考。
4- (void) playerThread: (void*)unused
5{
6audioRunLoop = CFRunLoopGetCurrent();//子線程的runloop引用
7NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];//子線程的
8[self initPlayer]; CFRunLoopRun(); //運(yùn)行子線程的
9[pool release]; ?// run loop,這里就會(huì)停住了骚勘。
10}
11//實(shí)現(xiàn)一個(gè)timer,用于檢查子線程的工作狀態(tài)铐伴,并在合適的時(shí)候做任務(wù)切換∏味铮或者是合適的時(shí)候停掉自己的
12-(void) initPlayer {
13//在這里你可以初始化一個(gè)工作類当宴,比如聲音或者視頻播放
14NSTimer *stateChange = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:
15@selector(checkStatuserInfo:nil repeats:YES];
16}
17-(void) checkState:(NSTimer*) timer
18{
19if(需要退出自線程了) {
20//釋放子線程里面的資源
21CFRunLoopStop( CFRunLoopGetCurrent());//結(jié)束子線程任務(wù)
22}
23}
3. NSThread、NSOperationQueue以及GCD等多線程編程技術(shù)什么情況下使用泽疆?
1)NSThread
優(yōu)點(diǎn):NSThread比其他兩個(gè)輕量級(jí)
缺點(diǎn):需要自己管理線程的生命周期户矢,線程同步。線程同步對(duì)數(shù)據(jù)的加鎖會(huì)有一定的系統(tǒng)開銷
2)Cocoa ?NSOperation
優(yōu)點(diǎn):不需要關(guān)心線程管理殉疼, 數(shù)據(jù)同步的事情梯浪,可以把精力放在自己需要執(zhí)行的操作上。
Cocoa operation相關(guān)的類是NSOperation, NSOperationQueue.
NSOperation是個(gè)抽象類,使用它必須用它的子類瓢娜,可以實(shí)現(xiàn)它或者使用它定義好的兩個(gè)子類: NSInvocationOperation和NSBlockOperation.
創(chuàng)建NSOperation子類的對(duì)象挂洛,把對(duì)象添加到NSOperationQueue隊(duì)列里執(zhí)行。
2)GCD使用過程中遇到的問題眠砾?
44.項(xiàng)目中哪塊用到多線程虏劲,碰到了什么問題,怎么解決的
什么時(shí)候使用多線程:
將耗時(shí)荠藤、輪詢或者并發(fā)需求高等任務(wù)分配到其他線程執(zhí)行伙单,并由主線程負(fù)責(zé)統(tǒng)一更新界面會(huì)使得應(yīng)用程序更加流暢,用戶體驗(yàn)更好哈肖,例如網(wǎng)絡(luò)請(qǐng)求,播放游戲的背景音樂吻育,文件下載等。
碰到的問題以及解決辦法:
(1)使用多線程時(shí)通常需要控制線程的并發(fā)數(shù)淤井,因?yàn)榫€程會(huì)消耗系統(tǒng)資源布疼,同時(shí)運(yùn)行的線程過多,系統(tǒng)會(huì)變慢
使用以下方法可以控制并發(fā)的線程數(shù)量:
-(void)setMaxConcurrentOperationCount:(NSInteger)cnt;
使用addDependency可以建立操作之間的依賴關(guān)系币狠,設(shè)定操作的執(zhí)行順序
(2)當(dāng)多個(gè)線程對(duì)同一個(gè)資源出現(xiàn)爭(zhēng)奪的時(shí)候需要注意線程安全問題
(3)更新UI界面游两,處理界面和用戶之間的交互事件一定要在主線程中處理。
‘多線程中棧與堆是公有的還是私有的
一般來說棧是私有的漩绵,堆是公有的贱案;但是可以為特定的線程創(chuàng)建私有的堆
在多線程環(huán)境下,每個(gè)線程擁有一個(gè)棧和一個(gè)程序計(jì)數(shù)器止吐。棧和程序計(jì)數(shù)器用來保存線程的執(zhí)行歷史和線程的執(zhí)行狀態(tài)宝踪,是線程私有的資源侨糟。其他的資源(比如堆、地址空間瘩燥、全局變量)是由同一個(gè)進(jìn)程內(nèi)的多個(gè)線程共享秕重。
堆: 是大家共有的空間,分全局堆和局部堆厉膀。全局堆就是所有沒有分配的空間溶耘,局部堆就是用戶分配的空間。堆在操作系統(tǒng)對(duì)進(jìn)程初始化的時(shí)候分配服鹅,運(yùn)行過程中也可以向系統(tǒng)要額外的堆凳兵,但是記得用完了要還給操作系統(tǒng),要不然就是內(nèi)存泄漏企软。
棧:是個(gè)線程獨(dú)有的留荔,保存其運(yùn)行狀態(tài)和局部自動(dòng)變量的。棧在線程開始的時(shí)候初始化澜倦,每個(gè)線程的棧互相獨(dú)立杰妓,因此藻治,棧是thread safe的。操作系統(tǒng)在切換線程的時(shí)候會(huì)自動(dòng)的切換棧巷挥,就是切換 SS/ESP寄存器桩卵。棧空間不需要在高級(jí)語言里面顯式的分配和釋放倍宾。
24雏节、描述runloop和線程的關(guān)系
Run loop,正如其名,loop表?示某種循環(huán),和run放在?一起就表?示?一直在運(yùn)?行著的循環(huán)。實(shí)際上,run loop和線程是緊密相連的,可以這樣說run loop是為了線程?而?生,沒有線程,它就沒有存在的必要高职。Run loops是線程的基礎(chǔ)架構(gòu)部分, Cocoa和CoreFundation都提供了run loop對(duì)象?方便配置和管理線程的run loop(以
下都已Cocoa為例)钩乍。每個(gè)線程,包括程序的主線程(main thread)都有與之相 應(yīng)的run loop對(duì)象。
8怔锌、GCD的隊(duì)列(dispatch_queue_t)分哪兩種類型?編寫代碼:使?用并?行隊(duì)列實(shí)現(xiàn)多線程開發(fā)
串?行隊(duì)列Serial Dispatch Queue
并?行隊(duì)列Concurrent Dispatch Queue
1
dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIO RITY_DEFAULT, 0);
2
dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIO
RITY_HIGH, 0);
3
dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIO RITY_LOW, 0);
25.(口述)是否使用過NSOperationQueue寥粹?如果用過或者了解的話,你為什么要使用NSOperationQueue埃元,實(shí)現(xiàn)了什么涝涤?請(qǐng)描述它和GCD的區(qū)別和類似的地方
26.(口述)在使用GCD以及block的時(shí)候要注意什么?他們倆是一回事兒?jiǎn)幔?/p>
5岛杀、列舉幾種進(jìn)程的同步機(jī)制并進(jìn)行比較阔拳。
(1)信號(hào)量機(jī)制 ? ?一個(gè)信號(hào)量只能置一次初值,以后只能對(duì)之進(jìn)行p操作或v操作类嗤。由此也可以看到糊肠,信號(hào)量機(jī)制必須有公共內(nèi)存辨宠,不能用于分布式操作系統(tǒng),這是它最大的弱點(diǎn)罪针。信號(hào)量機(jī)制功能強(qiáng)大彭羹,但使用時(shí)對(duì)信號(hào)量的操作分散, 而且難以控制泪酱,讀寫和維護(hù)都很困難派殷。加重了程序員的編碼負(fù)擔(dān);核心操作P-V分散在各用戶程序的代碼中墓阀,不易控制和管理毡惜;一旦錯(cuò)誤,后果嚴(yán)重斯撮,且不易發(fā)現(xiàn)和糾正经伙。
(2)自旋鎖 ?旋鎖是為了保護(hù)共享資源提出的一種鎖機(jī)制。調(diào)用者申請(qǐng)的資源如果被占用勿锅,即自旋鎖被已經(jīng)被別的執(zhí)行單元保持帕膜,則調(diào)用者一直循環(huán)在那里看是否該自旋鎖的保持著已經(jīng)釋放了鎖。自旋鎖是一種比較低級(jí)的保護(hù)數(shù)據(jù)結(jié)構(gòu)和代碼片段的原始方式溢十,可能會(huì)引起以下兩個(gè)問題; 1垮刹、死鎖2、過多地占用CPU資源 傳統(tǒng)自旋鎖由于無序競(jìng)爭(zhēng)會(huì)導(dǎo)致“公平性”問題
(3)管程 ?信號(hào)量機(jī)制功能強(qiáng)大张弛,但使用時(shí)對(duì)信號(hào)量的操作分散荒典,而且難以控制,讀寫和維護(hù)都很困難吞鸭。因此后來又提出了一種集中式同步進(jìn)程——管程寺董。其基本思想是將共享變量和對(duì)它們的操作集中在一個(gè)模塊中,操作系統(tǒng)或并發(fā)程序就由這樣的模塊構(gòu)成刻剥。這樣模塊之間聯(lián)系清晰遮咖,便于維護(hù)和修改,易于保證正確性造虏。
(4)會(huì)合 進(jìn)程直接進(jìn)行相互作用
(5)分布式系統(tǒng) 由于在分布式操作系統(tǒng)中沒有公共內(nèi)存盯滚,因此參數(shù)全為值參,而且不可為指針酗电。
http://my.oschina.net/starmier/blog/199834
6魄藕、導(dǎo)致進(jìn)程死鎖的原因是什么,如何解決撵术。
產(chǎn)生死鎖的原因:一是系統(tǒng)提供的資源數(shù)量有限背率,不能滿足每個(gè)進(jìn)程的使用;二是多道程序運(yùn)行時(shí),進(jìn)程推進(jìn)順序不合理寝姿。
產(chǎn)生死鎖的必要條件是:1交排、互斥條件;2饵筑、不可剝奪條件(不可搶占)埃篓;
3、部分分配根资;4架专、循環(huán)等待。
根據(jù)產(chǎn)生死鎖的四個(gè)必要條件玄帕,只要使其中之一不能成立部脚,死鎖就不會(huì)出現(xiàn)。為此裤纹,可以采取下列三種預(yù)防措施:
1委刘、采用資源靜態(tài)分配策略,破壞"部分分配"條件鹰椒;
2锡移、允許進(jìn)程剝奪使用其他進(jìn)程占有的資源,從而破壞"不可剝奪"條件漆际;
3罩抗、采用資源有序分配法,破壞"環(huán)路"條件灿椅。
死鎖的避免不嚴(yán)格地限制死鎖的必要條件的存在,而是系統(tǒng)在系統(tǒng)運(yùn)行過程中小心地避免死鎖的最終發(fā)生钞支。最著名的死鎖避免算法是銀行家算法茫蛹。死鎖避免算法需要很大的系統(tǒng)開銷。
解決死鎖的另一條途徑是死鎖檢測(cè)方法烁挟,這種方法對(duì)資源的分配不加限制婴洼,即允許死鎖的發(fā)生。但系統(tǒng)定時(shí)地運(yùn)行一個(gè)"死鎖檢測(cè)"程序撼嗓,判斷系統(tǒng)是否已發(fā)生死鎖柬采,若檢測(cè)到死鎖發(fā)生則設(shè)法加以解除。
解除死鎖常常采用下面兩種方法:1且警、資源剝奪法粉捻;2、撤消進(jìn)程法
解決策略:鴕鳥策略斑芜、預(yù)防策略肩刃、避免策略、檢測(cè)與解除死鎖
http://www.cnblogs.com/Jessy/p/3540724.html
1、列舉Cocoa中常見對(duì)幾種線程的實(shí)現(xiàn)盈包,并談?wù)劧嗑€程安全的幾種解決辦法和多線程安全怎么控制.
Cocoa中常見對(duì)幾種線程的實(shí)現(xiàn):
(1)OC的NSThread
(2) C語言的GCD接口(性能最好沸呐,代碼更精簡(jiǎn))
(3) OC的NSOperation和NSOperationQueue(基于GCD)
多線程安全的幾種解決辦法
(1)只在主線程刷新訪問UI
(2)如果要防止資源搶奪,得用synchronize進(jìn)行加鎖保護(hù)呢燥。
(3)如果異步操作要保證線程安全等問題崭添,盡量使用GCD。(GCD有些函數(shù)默認(rèn)就是安全的)
http://www.cnphp6.com/archives/61953
7.線程注意事項(xiàng)
關(guān)于多線程的詳細(xì)介紹
http://mobile.51cto.com/iphone-403490.htm
1叛氨、線程的堆棧大小
iPhone設(shè)備上的應(yīng)用程序開發(fā)也是屬于嵌入式設(shè)備的開發(fā)呼渣,同樣需要注意嵌入式設(shè)備開發(fā)時(shí)的幾點(diǎn)問題,比如資源上限力试,處理器速度等徙邻。
iPhone中的線程應(yīng)用并不是無節(jié)制的,官方給出的資料顯示iPhone OS下的主線程的堆棧大小是1M畸裳,第二個(gè)線程開始都是512KB缰犁。并且該值不能通過編譯器開關(guān)或線程API函數(shù)來更改。
2怖糊、Autorelease
如果你什么都不考慮帅容,在線程函數(shù)內(nèi)調(diào)用autorelease,會(huì)出現(xiàn)錯(cuò)誤
3伍伤、子線程中描畫窗口
多線程編程中普遍遵循一個(gè)原則并徘,就是一切與UI相關(guān)的操作都有主線程做,子線程只負(fù)責(zé)事務(wù)扰魂,數(shù)據(jù)方面的處理麦乞。那么如果想在子線程中更新UI時(shí)怎么做呢?如果是在windows下劝评,你會(huì)PostMessage一個(gè)描畫更新的消息姐直,在iPhone中,需要使用performSelectorOnMainThread委托主線程處理蒋畜。
總結(jié):
多線程能適當(dāng)提高程序的執(zhí)行效率声畏,能適當(dāng)提高資源利用率(CPU、內(nèi)存利用率)姻成,但是開啟線程需要占用一定的內(nèi)存空間(默認(rèn)情況下插龄,主線程占用1M,子線程占用512KB)科展,如果開啟大量的線程均牢,會(huì)占用大量的內(nèi)存空間,降低程序的性能才睹,而且線程越多膨处,CPU在調(diào)度線程上的開銷就越大见秤,使用多線程程序設(shè)計(jì)更加復(fù)雜:比如線程之間的通信、多線程的數(shù)據(jù)共享
一個(gè)iOS程序運(yùn)行后真椿,默認(rèn)會(huì)開啟1條線程鹃答,稱為“主線程”或“UI線程”
主線程的使用注意:別將比較耗時(shí)的操作放到主線程中。耗時(shí)操作會(huì)卡住主線程突硝,嚴(yán)重影響UI的流暢度测摔,給用戶一種“卡”的壞體驗(yàn)
19.多線程在實(shí)際項(xiàng)目中的應(yīng)用中有沒有碰到什么問題
什么時(shí)候使用多線程:
將耗時(shí)、輪詢或者并發(fā)需求高等任務(wù)分配到其他線程執(zhí)行解恰,并由主線程負(fù)責(zé)統(tǒng)一更新界面會(huì)使得應(yīng)用程序更加流暢锋八,用戶體驗(yàn)更好,例如網(wǎng)絡(luò)請(qǐng)求,播放游戲的背景音樂护盈,文件下載等挟纱。
碰到的問題以及解決辦法:
(1)使用多線程時(shí)通常需要控制線程的并發(fā)數(shù),因?yàn)榫€程會(huì)消耗系統(tǒng)資源腐宋,同時(shí)運(yùn)行的線程過多紊服,系統(tǒng)會(huì)變慢
使用以下方法可以控制并發(fā)的線程數(shù)量:
-(void)setMaxConcurrentOperationCount:(NSInteger)cnt;
使用addDependency可以建立操作之間的依賴關(guān)系,設(shè)定操作的執(zhí)行順序
(2)當(dāng)多個(gè)線程對(duì)同一個(gè)資源出現(xiàn)爭(zhēng)奪的時(shí)候需要注意線程安全問題
(3)更新UI界面胸竞,處理界面和用戶之間的交互事件一定要在主線程中處理
1.dispatch_async(dispatch_get_mian_queue(),^{//這里應(yīng)該寫哪些代碼欺嗤?}
"m???V??