iOS開發中關於多線程的問題(NSOperationQueue,NSThread,GCD)

1.多線程的優點和缺點分別是什麼?
答:優點:1、將耗時較長的操作(網絡請求、圖片下載、音頻下載、數據庫訪問等)放在子線程中執行,可以防止主線程的卡死;2、可以發揮多核處理的優勢,提升cpu的使用率。
      缺點:1、每開闢一個子線程就消耗一定的資源; 2、會造成代碼的可讀性變差;3、如果出現多個線程同時訪問一個資源,會出現資源爭奪的情況
3. 2.NSOperationQueue中有一個屬性叫maxConcurrentCount即最大併發數。這裏所謂的最大併發數指的是什麼含義?
答:這裏的最大併發數指得是在隊列中同時執行的任務的個數。有很多人會認爲是所分配的線程的個數。其實不是的。因爲線程的個數的多少取決於系統,系統會分配合適的線程數量來保證這些任務併發執行的,作爲程序員我們是沒辦法控制的
4NSThread中的Runloop的作用,如何使用?
每個線程(NSThread)對象中內部都有一個run loopNSRunLoop)對象用來循環處理輸入事件,處理的事件包括兩類,一是來自Input sources的異步事件,一是來自Timer sources的同步事件;run Loop在處理輸入事件時會產生通知,可以通過Core Foundation向線程中添加run-loop observers來監聽特定事件,以在監聽的事件發生時做附加的處理工作。 主線程的Run Loop會在App運行時自動運行,子線程中需要手動運行。Run Loop就是一個處理事件源的循環,你可以控制這個Run Loop運行多久,如果當前沒有事件發生,Run Loop會讓這個線程進入睡眠狀態(避免再浪費CPU時間),如果有事件發生,Run Loop就處理這個事件。如果子線程進入一個循環需要不斷處理一些事件,那麼設置一個Run Loop是最好的處理方式,如果需要Timer,那麼Run Loop就是必須的。
 
開發中遇到的需要使用Run Loop的情況有:
需要使用Port或者自定義Input Source與其他線程進行通訊。
子線程中使用了定時器
使用任何perform mSelector*****到子線程中運行方法
使用子線程去執行週期性任務
NSURLConnection在子線程中發起異步請求
 
 10OC中創建線程的方法是什麼?如果在主線程中執行代碼,方法是什麼
線程創建有三種方法:使用NSThread創建、使用 GCDdispatch、使用子類化的 NSOperation,然後將其加入NSOperationQueue;在主線程執行代碼,方法是performSelectorOnMainThread,如果想延時執行代碼可以用performSelector:onThread:withObject:waitUntilDone:
 
11)線程和進程的區別和聯繫
進程和線程都是由操作系統所體會的程序運行的基本單元,系統利用該基本單元實現系統對應用的併發性。 
 
進程和線程的主要差別在於它們是不同的操作系統資源管理方式。進程有獨立的地址空間,一個進程崩潰後,在保護模式下不會對其它進程產生影響,而線程只是一個進程中的不同執行路徑。線程有自己的堆棧和局部變量,但線程之間沒有單獨的地址空間,一個線程死掉就等於整個進程死掉,所以多進程的程序要比多線程的程序健壯,但在進程切換時,耗費資源較大,效率要差一些。但對於一些要求同時進行並且又要共享某些變量的併發操作,只能用線程,不能用進程
 
 
9.在項目什麼時候選擇使用GCD,什麼時候選擇NSOperation 
 
gcd是基於c的底層apiNSOperation屬於object-c類。
相對於gcd
1NSOperation擁有更多的函數可用,具體查看api
2,在NSOperationQueue中,可以建立各個NSOperation之間的依賴關係。
3,有kvo,可以監測operation是否正在執行(isExecuted)、是否結束(isFinished),是否取消(isCanceld)。
4NSOperationQueue可以方便的管理併發、NSOperation之間的優先級。
gcd主要與block結合使用。
 
項目中使用NSOperation的優點是NSOperation是對線程的高度抽象,在項目中使用它,會使項目的程序結構更好,子類化NSOperation的設計思路,是具有面向對象的優點(複用、封裝),使得實現是多線程支持,而接口簡單,建議在複雜項目中使用。
項目中使用GCD的優點是GCD本身非常簡單、易用,對於不復雜的多線程操作,會節省代碼量,而Block參數的使用,會是代碼更爲易讀,建議在簡單項目中使用。
 
1、線程的堆棧大小
 
iPhone設備上的應用程序開發也是屬於嵌入式設備的開發,同樣需要注意嵌入式設備開發時的幾點問題,比如資源上限,處理器速度等。
iPhone 中的線程應用並不是無節制的,官方給出的資料顯示iPhone OS下的主線程的堆棧大小是1M,第二個線程開始都是512KB。並且該值不能通過編譯器開關或線程API函數來更改。
 
2Autorelease
如果你什麼都不考慮,在線程函數內調用 autorelease,會出現錯誤
 
3、子線程中描畫窗口
多線程編程中普遍遵循一個原則,就是一切與UI相關的操作都有主線程做,子線程只負責事務,數據方面的處理。那麼如果想在子線程中更新UI時怎麼做呢?如果是在windows下,你會 PostMessage 一個描畫更新的消息,在iPhone中,需要使用performSelectorOnMainThread 委託主線程處理。
 
總結:
多線程能適當提高程序的執行效率,能適當提高資源利用率(CPU、內存利用率),但是開啓線程需要佔用一定的內存空間(默認情況下,主線程佔用1M,子線程佔用512KB),如果開啓大量的線程,會佔用大量的內存空間,降低程序的性能,而且線程越多,CPU在調度線程上的開銷就越大,使用多線程程序設計更加複雜:比如線程之間的通信、多線程的數據共享
 
一個iOS程序運行後,默認會開啓1條線程,稱爲“主線程”或“UI線程”
主線程的使用注意:別將比較耗時的操作放到主線程中。耗時操作會卡住主線程,嚴重影響UI的流暢度,給用戶一種“卡”的壞體驗
25. 線程是什麼?進程是什麼?二者有什麼區別和聯繫? UI第二十二講 多線程編程)
線程是CPU獨立運行和獨立調度的基本單位(可以理解爲一個進程中執行的代碼片段),進程是資源分配的基本單位(進程是一塊包含了某些資源的內存區域)。進程是線程的容器,真正完成代碼執行的是線程,而進程則作爲線程的執行環境。一個程序至少包含一個進程,一個進程至少包含一個線程,一個進程中的多個線程共享當前進程所擁有的資源。
 
26.談談你對多線程開發的理解?ios中有幾種實現多線程的方法?(UI第二十二講 多線程編程)
好處:
①、使用線程可以把程序中佔據時間長的任務放到後臺去處理,如圖片、視頻的下載
②、發揮多核處理器的優勢,併發執行讓系統運行的更快、更流暢,用戶體驗更好
缺點:
①、大量的線程降低代碼的可讀性,
②、更多的線程需要更多的內存空間
③、當多個線程對同一個資源出現爭奪的時候要注意線程安全的問題。
iOS有三種多線程編程的技術:
①、NSThread(兩種創建方式)
[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:^{
//這個block語句塊在子線程中執行
}

③、Grand Central Dispatch (GCD)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // 耗時的操作
    dispatch_async(dispatch_get_main_queue(), ^{
        // 更新界面
    });
});

PS:不顯示的創建線程的方法:
NSObject的類方法 performSelectorInBackground:withObject:
創建一個線程:
[Obj performSelectorInBackground:@selector(doSomething) withObject:nil];
 
 
27.線程同步和異步的區別?IOS中如何實現多線程的同步?
同步:一個線程要等待上一個線程執行完之後才能執行當前的線程,生活中的例子(上廁所)。
異步:同時去做兩件或者多件事。比如邊聽歌邊看報。
.runloop和線程有什麼關係?
總的說來,Run loop,正如其名,loop表示某種循環,和run放在一起就表示一直在運行着的循環。實際上,run loop和線程是緊密相連的,可以這樣說run loop是爲了線程而生,沒有線程,它就沒有存在的必要。Run loops是線程的基礎架構部分, Cocoa CoreFundation 都提供了 run loop 對象方便配置和管理線程的 run loop (以下都以 Cocoa 爲例)。每個線程,包括程序的主線程( main thread )都有與之相應的 run loop 對象。
runloop 和線程的關係:主線程的run loop默認是啓動的。iOS的應用程序裏面,程序啓動後會有一個如下的main()函數
int main(int argc, char * argv[]) {
@autoreleasepool {
         return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
重點是UIApplicationMain()函數,這個方法會爲main thread設置一個NSRunLoop對象,這就解釋了:爲什麼我們的應用可以在無人操作的時候休息,需要讓它幹活的時候又能立馬響應。
對其它線程來說,run loop默認是沒有啓動的,如果你需要更多的線程交互則可以手動配置和啓動,如果線程只是去執行一個長時間的已確定的任務則不需要。
在任何一個 Cocoa 程序的線程中,都可以通過以下代碼來獲取到當前線程的 run loop
NSRunLoop *runloop = [NSRunLoop currentRunLoop];
51. GCD的隊列(dispatch_queue_t)分哪兩種類型?
串行隊列Serial Dispatch Queue
並行隊列Concurrent Dispatch Queue
77. 你參與的APP,是如何處理多個服務的同步發起的?
使用iOS線程技術,創建並行隊列來分別執行不同的任務。將不同的任務加入到子隊列當中,任務執行後回到主線程當中刷新UI界面。
APP 界面一般都是根據產品需求和UI效果圖來完成的,但是我們爲了提高代碼的複用性,會將視圖的實現進行封裝,然後在控制器當中進行加載用
88.NSOperationQueue有哪些使用方式?
一種在iOS中執行併發操作的方法,是使用NSOperationNSOperationQueue類。在本教程中,你將學習如何使用它們!你會先創建一款不使用多線程的app,這樣它會變得響應非常遲鈍。然後改進程序,添加上並行操作–並且希望–可以提供一個交互響應更好的界面給用戶!
另一種處理操作之間的依賴關係,如果操作直接有依賴關係,比如第二個操作必須等第一個操作結束後再執行。控制線程池中的線程數
89.NSThread中的Runloop的作用,如何使用?
有些情況下,我們還是在運行一些長線任務或者複雜任務的時候需要用比較原始的NSThread。這就需要爲NSThread創建一個run loop.
          1 NSThread *thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(playerThread: ) object:nil];  
         2       [thread start];  
         3       //如果要利用NSOperation,原理類似。只需要加入到queue裏面去就好了。。queue會在合適的時機調用方法,下面代碼作爲參考。  
         4       - (void) playerThread: (void*)unused   
         5       {   
         6       audioRunLoop = CFRunLoopGetCurrent();//子線程的runloop引用 
         7       NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];//子線程的  
         8       [self initPlayer]; CFRunLoopRun(); //運行子線程的  
         9       [pool release];  // run loop,這裏就會停住了。
         10     }  
         11      // 實現一個timer,用於檢查子線程的工作狀態,並在合適的時候做任務切換。或者是合適的時候停掉自己的
 
         12      -(void) initPlayer {   
         13      // 在這裏你可以初始化一個工作類,比如聲音或者視頻播放   
         14      NSTimer *stateChange = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:  
         15        @selector(checkStatuserInfo:nil repeats:YES];  
         16      }  
         17      -(void) checkState:(NSTimer*) timer   
         18      {   
         19      if(需要退出自線程了) {  
         20      //釋放子線程裏面的資源  
         21      CFRunLoopStop( CFRunLoopGetCurrent());//結束子線程任務  
         22      }   
         23     } 
3. NSThreadNSOperationQueue以及GCD等多線程編程技術什麼情況下使用?
 
1NSThread
優點:NSThread 比其他兩個輕量級
缺點:需要自己管理線程的生命週期,線程同步。線程同步對數據的加鎖會有一定的系統開銷
 

2Cocoa  NSOperation
優點:不需要關心線程管理, 數據同步的事情,可以把精力放在自己需要執行的操作上。
Cocoa operation相關的類是NSOperation, NSOperationQueue.
NSOperation是個抽象類,使用它必須用它的子類,可以實現它或者使用它定義好的兩個子類: NSInvocationOperationNSBlockOperation.
創建NSOperation子類的對象,把對象添加到NSOperationQueue隊列裏執行。
2GCD使用過程中遇到的問題?
 
44.項目中哪塊用到多線程,碰到了什麼問題,怎麼解決的
 
什麼時候使用多線程:
將耗時、輪詢或者併發需求高等任務分配到其他線程執行,並由主線程負責統一更新界面會使得應用程序更加流暢,用戶體驗更好,例如網絡請求,播放遊戲的背景音樂,文件下載等。
 
碰到的問題以及解決辦法:
1)使用多線程時通常需要控制線程的併發數,因爲線程會消耗系統資源,同時運行的線程過多,系統會變慢
使用以下方法可以控制併發的線程數量:
-(void)setMaxConcurrentOperationCount:(NSInteger)cnt;
使用addDependency可以建立操作之間的依賴關係,設定操作的執行順序
2)當多個線程對同一個資源出現爭奪的時候需要注意線程安全問題
3)更新UI界面,處理界面和用戶之間的交互事件一定要在主線程中處理。
‘多線程中棧與堆是公有的還是私有的
一般來說棧是私有的,堆是公有的;但是可以爲特定的線程創建私有的堆
 
在多線程環境下,每個線程擁有一個棧和一個程序計數器。棧和程序計數器用來保存線程的執行歷史和線程的執行狀態,是線程私有的資源。其他的資源(比如堆、地址空間、全局變量)是由同一個進程內的多個線程共享。
 
堆: 是大家共有的空間,分全局堆和局部堆。全局堆就是所有沒有分配的空間,局部堆就是用戶分配的空間。堆在操作系統對進程初始化的時候分配,運行過程中也可以向系統要額外的堆,但是記得用完了要還給操作系統,要不然就是內存泄漏。
棧:是個線程獨有的,保存其運行狀態和局部自動變量的。棧在線程開始的時候初始化,每個線程的棧互相獨立,因此,棧是 thread safe的。操作系統在切換線程的時候會自動的切換棧,就是切換 SS/ESP寄存器。棧空間不需要在高級語言裏面顯式的分配和釋放。
 
24、描述runloop和線程的關係
Run loop,正如其名,loop表⽰示某種循環,和run放在⼀一起就表⽰示⼀一直在運⾏行着 的循環。實際上,run loop和線程是緊密相連的,可以這樣說run loop是爲了線 程⽽而⽣生,沒有線程,它就沒有存在的必要。Run loops是線程的基礎架構部分, Cocoa和CoreFundation都提供了run loop對象⽅方便配置和管理線程的run loop(以
下都已Cocoa爲例)。每個線程,包括程序的主線程(main thread)都有與之相 應的run loop對象。
 
8、GCD的隊列(dispatch_queue_t)分哪兩種類型?編寫代碼:使⽤用並⾏行隊列 實現多線程開發
串⾏行隊列Serial Dispatch Queue
並⾏行隊列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);

1、列舉Cocoa中常見對幾種線程的實現,並談談多線程安全的幾種解決辦法和多線程安全怎麼控制.
 
Cocoa中常見對幾種線程的實現:
(1)OCNSThread
(2) C語言的GCD接口(性能最好,代碼更精簡) 
(3) OCNSOperationNSOperationQueue(基於GCD
 
多線程安全的幾種解決辦法
 (1)只在主線程刷新訪問UI
 (2)如果要防止資源搶奪,得用synchronize進行加鎖保護。
 (3)如果異步操作要保證線程安全等問題,儘量使用GCD。(GCD有些函數默認就是安全的)


19.多線程在實際項目中的應用中有沒有碰到什麼問題什麼時候使用多線程:
將耗時、輪詢或者併發需求高等任務分配到其他線程執行,並由主線程負責統一更新界面會使得應用程序更加流暢,用戶體驗更好,例如網絡請求,播放遊戲的背景音樂,文件下載等。
 
       碰到的問題以及解決辦法:
       (1)使用多線程時通常需要控制線程的併發數,因爲線程會消耗系統資源,同時運行的線程過多,系統會變慢
       使用以下方法可以控制併發的線程數量:
       -(void)setMaxConcurrentOperationCount:(NSInteger)cnt;
       使用addDependency可以建立操作之間的依賴關係,設定操作的執行順序
       (2)當多個線程對同一個資源出現爭奪的時候需要注意線程安全問題
       (3)更新UI界面,處理界面和用戶之間的交互事件一定要在主線程中處理
3. 2.NSOperationQueue中有一個屬性叫maxConcurrentCount即最大併發數。這裏所謂的最大併發數指的是什麼含義?
答:這裏的最大併發數指得是在隊列中同時執行的任務的個數。有很多人會認爲是所分配的線程的個數。其實不是的。因爲線程的個數的多少取決於系統,系統會分配合適的線程數量來保證這些任務併發執行的,作爲程序員我們是沒辦法控制的
4.在項目中什麼時候選擇使用GCD,什麼時候選擇使用NSOperation
答:無論是GCD還是NSOperation其實都是多線程的一種實現形式。嚴格的說NSOperation和線程並沒有必然聯繫,更不是多線程,NSOperation只是操作,封裝了targetaction 或者Block,在主線程中執行OperationOperation就會運行在主線程中,在子線程中執行OperationOperation就運行在子線程中。它只有和NSOperationQueue聯合使用的時候,才能發揮出價值。NSOperationQueueOperation的管理者,它首先是一個隊列,先來的任務先開始執行,後來的任務後開始執行,這些任務的執行是併發的,NSOperationQueue負責爲任務開闢線程以及關閉線程,有點類似於cell重用,用有限的線程執行任意數量的任務,同時可以設置最大併發數,控制程序的性能,不至於全部任務一起執行。GCD出現比NSOperationQueue要晚,是一套基於C函數的API,由於是C函數,所以性能比較高,使用靈活,安全,當然功能也強大。但是相對於GCD來講,NSOperationQueue對線程做了封裝,使用比較簡單,尤其是不用管理線程的開啓和關閉。個人認爲,如果僅僅是想要實現異步執行任務,首選GCD,如果要管理多個異步任務,NSoperationQueue比較方便。如果要做更復雜的處理,比如前5個任務併發,5個任務執行完之後,需要串行執行3個任務,之後再併發執行若干任務,就需要使用GCD了。總的來說,特別簡單的和非常複雜的多線程任務GCD比較適合,介於二者之間的用NSOperationQueue比較合適。
5.寫出在多線程情況下的一個單例。
答:一般情況下,在開發中我們所寫的單例都是僞單例。即只是保證了在調用某一方法時,所產生的對象只有一個,但是沒有考慮其他的影響其引用計數的方法。例如retaincopy等。爲了保證線程安全,單例的寫法如下所示:
方法一:
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; 
}

 10OC中創建線程的方法是什麼?如果在主線程中執行代碼,方法是什麼
線程創建有三種方法:使用NSThread創建、使用 GCDdispatch、使用子類化的 NSOperation,然後將其加入NSOperationQueue;在主線程執行代碼,方法是performSelectorOnMainThread,如果想延時執行代碼可以用performSelector:onThread:withObject:waitUntilDone:
 
11)線程和進程的區別和聯繫
進程和線程都是由操作系統所體會的程序運行的基本單元,系統利用該基本單元實現系統對應用的併發性。 進程和線程的主要差別在於它們是不同的操作系統資源管理方式。進程有獨立的地址空間,一個進程崩潰後,在保護模式下不會對其它進程產生影響,而線程只是一個進程中的不同執行路徑。線程有自己的堆棧和局部變量,但線程之間沒有單獨的地址空間,一個線程死掉就等於整個進程死掉,所以多進程的程序要比多線程的程序健壯,但在進程切換時,耗費資源較大,效率要差一些。但對於一些要求同時進行並且又要共享某些變量的併發操作,只能用線程,不能用進程
 
2Autorelease
如果你什麼都不考慮,在線程函數內調用 autorelease,會出現錯誤
 
3、子線程中描畫窗口
多線程編程中普遍遵循一個原則,就是一切與UI相關的操作都有主線程做,子線程只負責事務,數據方面的處理。那麼如果想在子線程中更新UI時怎麼做呢?如果是在windows下,你會 PostMessage 一個描畫更新的消息,在iPhone中,需要使用performSelectorOnMainThread 委託主線程處理。
 
總結:
多線程能適當提高程序的執行效率,能適當提高資源利用率(CPU、內存利用率),但是開啓線程需要佔用一定的內存空間(默認情況下,主線程佔用1M,子線程佔用512KB),如果開啓大量的線程,會佔用大量的內存空間,降低程序的性能,而且線程越多,CPU在調度線程上的開銷就越大,使用多線程程序設計更加複雜:比如線程之間的通信、多線程的數據共享
 
一個iOS程序運行後,默認會開啓1條線程,稱爲“主線程”或“UI線程”
主線程的使用注意:別將比較耗時的操作放到主線程中。耗時操作會卡住主線程,嚴重影響UI的流暢度,給用戶一種“卡”的壞體驗
25. 線程是什麼?進程是什麼?二者有什麼區別和聯繫? UI第二十二講 多線程編程)
線程是CPU獨立運行和獨立調度的基本單位(可以理解爲一個進程中執行的代碼片段),進程是資源分配的基本單位(進程是一塊包含了某些資源的內存區域)。進程是線程的容器,真正完成代碼執行的是線程,而進程則作爲線程的執行環境。一個程序至少包含一個進程,一個進程至少包含一個線程,一個進程中的多個線程共享當前進程所擁有的資源。
 
26.談談你對多線程開發的理解?ios中有幾種實現多線程的方法?(UI第二十二講 多線程編程)
好處:
①、使用線程可以把程序中佔據時間長的任務放到後臺去處理,如圖片、視頻的下載
②、發揮多核處理器的優勢,併發執行讓系統運行的更快、更流暢,用戶體驗更好
缺點:
①、大量的線程降低代碼的可讀性,
②、更多的線程需要更多的內存空間
③、當多個線程對同一個資源出現爭奪的時候要注意線程安全的問題。
iOS有三種多線程編程的技術:
①、NSThread(兩種創建方式)
[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:^{
//這個block語句塊在子線程中執行
}

③、Grand Central Dispatch (GCD)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // 耗時的操作
    dispatch_async(dispatch_get_main_queue(), ^{
        // 更新界面
    });
});

PS:不顯示的創建線程的方法:
NSObject的類方法 performSelectorInBackground:withObject:
創建一個線程:
[Obj performSelectorInBackground:@selector(doSomething) withObject:nil];
 
 
27.線程同步和異步的區別?IOS中如何實現多線程的同步?
同步:一個線程要等待上一個線程執行完之後才能執行當前的線程,生活中的例子(上廁所)。
異步:同時去做兩件或者多件事。比如邊聽歌邊看報。
.runloop和線程有什麼關係?
總的說來,Run loop,正如其名,loop表示某種循環,和run放在一起就表示一直在運行着的循環。實際上,run loop和線程是緊密相連的,可以這樣說run loop是爲了線程而生,沒有線程,它就沒有存在的必要。Run loops是線程的基礎架構部分, Cocoa CoreFundation 都提供了 run loop 對象方便配置和管理線程的 run loop (以下都以 Cocoa 爲例)。每個線程,包括程序的主線程( main thread )都有與之相應的 run loop 對象。
runloop 和線程的關係:主線程的run loop默認是啓動的。iOS的應用程序裏面,程序啓動後會有一個如下的main()函數
int main(int argc, char * argv[]) {
@autoreleasepool {
         return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
重點是UIApplicationMain()函數,這個方法會爲main thread設置一個NSRunLoop對象,這就解釋了:爲什麼我們的應用可以在無人操作的時候休息,需要讓它幹活的時候又能立馬響應。
對其它線程來說,run loop默認是沒有啓動的,如果你需要更多的線程交互則可以手動配置和啓動,如果線程只是去執行一個長時間的已確定的任務則不需要。
在任何一個 Cocoa 程序的線程中,都可以通過以下代碼來獲取到當前線程的 run loop
NSRunLoop *runloop = [NSRunLoop currentRunLoop];
51. GCD的隊列(dispatch_queue_t)分哪兩種類型?
串行隊列Serial Dispatch Queue
並行隊列Concurrent Dispatch Queue
77. 你參與的APP,是如何處理多個服務的同步發起的?
使用iOS線程技術,創建並行隊列來分別執行不同的任務。將不同的任務加入到子隊列當中,任務執行後回到主線程當中刷新UI界面。
APP 界面一般都是根據產品需求和UI效果圖來完成的,但是我們爲了提高代碼的複用性,會將視圖的實現進行封裝,然後在控制器當中進行加載調用
88.NSOperationQueue有哪些使用方式?
一種在iOS中執行併發操作的方法,是使用NSOperationNSOperationQueue類。在本教程中,你將學習如何使用它們!你會先創建一款不使用多線程的app,這樣它會變得響應非常遲鈍。然後改進程序,添加上並行操作–並且希望–可以提供一個交互響應更好的界面給用戶!
另一種處理操作之間的依賴關係,如果操作直接有依賴關係,比如第二個操作必須等第一個操作結束後再執行。控制線程池中的線程數

3. NSThreadNSOperationQueue以及GCD等多線程編程技術什麼情況下使用?
 
1NSThread
優點:NSThread 比其他兩個輕量級
缺點:需要自己管理線程的生命週期,線程同步。線程同步對數據的加鎖會有一定的系統開銷
 
 
2Cocoa  NSOperation
優點:不需要關心線程管理, 數據同步的事情,可以把精力放在自己需要執行的操作上。
Cocoa operation相關的類是NSOperation, NSOperationQueue.
NSOperation是個抽象類,使用它必須用它的子類,可以實現它或者使用它定義好的兩個子類: NSInvocationOperationNSBlockOperation.
創建NSOperation子類的對象,把對象添加到NSOperationQueue隊列裏執行。

 
44.項目中哪塊用到多線程,碰到了什麼問題,怎麼解決的
 
什麼時候使用多線程:
將耗時、輪詢或者併發需求高等任務分配到其他線程執行,並由主線程負責統一更新界面會使得應用程序更加流暢,用戶體驗更好,例如網絡請求,播放遊戲的背景音樂,文件下載等。
 
碰到的問題以及解決辦法:
1)使用多線程時通常需要控制線程的併發數,因爲線程會消耗系統資源,同時運行的線程過多,系統會變慢
使用以下方法可以控制併發的線程數量:
-(void)setMaxConcurrentOperationCount:(NSInteger)cnt;
使用addDependency可以建立操作之間的依賴關係,設定操作的執行順序
2)當多個線程對同一個資源出現爭奪的時候需要注意線程安全問題
3)更新UI界面,處理界面和用戶之間的交互事件一定要在主線程中處理。
‘多線程中棧與堆是公有的還是私有的
一般來說棧是私有的,堆是公有的;但是可以爲特定的線程創建私有的堆
 
在多線程環境下,每個線程擁有一個棧和一個程序計數器。棧和程序計數器用來保存線程的執行歷史和線程的執行狀態,是線程私有的資源。其他的資源(比如堆、地址空間、全局變量)是由同一個進程內的多個線程共享。
 
堆: 是大家共有的空間,分全局堆和局部堆。全局堆就是所有沒有分配的空間,局部堆就是用戶分配的空間。堆在操作系統對進程初始化的時候分配,運行過程中也可以向系統要額外的堆,但是記得用完了要還給操作系統,要不然就是內存泄漏。
棧:是個線程獨有的,保存其運行狀態和局部自動變量的。棧在線程開始的時候初始化,每個線程的棧互相獨立,因此,棧是 thread safe的。操作系統在切換線程的時候會自動的切換棧,就是切換 SS/ESP寄存器。棧空間不需要在高級語言裏面顯式的分配和釋放。

1、列舉Cocoa中常見對幾種線程的實現,並談談多線程安全的幾種解決辦法和多線程安全怎麼控制.
 
Cocoa中常見對幾種線程的實現:
(1)OCNSThread
(2) C語言的GCD接口(性能最好,代碼更精簡) 
(3) OCNSOperationNSOperationQueue(基於GCD
 
多線程安全的幾種解決辦法
 (1)只在主線程刷新訪問UI
 (2)如果要防止資源搶奪,得用synchronize進行加鎖保護。
 (3)如果異步操作要保證線程安全等問題,儘量使用GCD。(GCD有些函數默認就是安全的)

3. 2.NSOperationQueue中有一個屬性叫maxConcurrentCount即最大併發數。這裏所謂的最大併發數指的是什麼含義?
答:這裏的最大併發數指得是在隊列中同時執行的任務的個數。有很多人會認爲是所分配的線程的個數。其實不是的。因爲線程的個數的多少取決於系統,系統會分配合適的線程數量來保證這些任務併發執行的,作爲程序員我們是沒辦法控制的
4.在項目中什麼時候選擇使用GCD,什麼時候選擇使用NSOperation
答:無論是GCD還是NSOperation其實都是多線程的一種實現形式。嚴格的說NSOperation和線程並沒有必然聯繫,更不是多線程,NSOperation只是操作,封裝了targetaction 或者Block,在主線程中執行OperationOperation就會運行在主線程中,在子線程中執行OperationOperation就運行在子線程中。它只有和NSOperationQueue聯合使用的時候,才能發揮出價值。NSOperationQueueOperation的管理者,它首先是一個隊列,先來的任務先開始執行,後來的任務後開始執行,這些任務的執行是併發的,NSOperationQueue負責爲任務開闢線程以及關閉線程,有點類似於cell重用,用有限的線程執行任意數量的任務,同時可以設置最大併發數,控制程序的性能,不至於全部任務一起執行。GCD出現比NSOperationQueue要晚,是一套基於C函數的API,由於是C函數,所以性能比較高,使用靈活,安全,當然功能也強大。但是相對於GCD來講,NSOperationQueue對線程做了封裝,使用比較簡單,尤其是不用管理線程的開啓和關閉。個人認爲,如果僅僅是想要實現異步執行任務,首選GCD,如果要管理多個異步任務,NSoperationQueue比較方便。如果要做更復雜的處理,比如前5個任務併發,5個任務執行完之後,需要串行執行3個任務,之後再併發執行若干任務,就需要使用GCD了。總的來說,特別簡單的和非常複雜的多線程任務GCD比較適合,介於二者之間的用NSOperationQueue比較合適。
5.寫出在多線程情況下的一個單例。
答:一般情況下,在開發中我們所寫的單例都是僞單例。即只是保證了在調用某一方法時,所產生的對象只有一個,但是沒有考慮其他的影響其引用計數的方法。例如retaincopy等。爲了保證線程安全,單例的寫法如下所示:
方法一:
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; 
}
4NSThread中的Runloop的作用,如何使用?
每個線程(NSThread)對象中內部都有一個run loopNSRunLoop)對象用來循環處理輸入事件,處理的事件包括兩類,一是來自Input sources的異步事件,一是來自Timer sources的同步事件;
run Loop在處理輸入事件時會產生通知,可以通過Core Foundation向線程中添加run-loop observers來監聽特定事件,以在監聽的事件發生時做附加的處理工作。 主線程的Run Loop會在App運行時自動運行,子線程中需要手動運行。


 
Run Loop就是一個處理事件源的循環,你可以控制這個Run Loop運行多久,如果當前沒有事件發生,Run Loop會讓這個線程進入睡眠狀態(避免再浪費CPU時間),如果有事件發生,Run Loop就處理這個事件。
如果子線程進入一個循環需要不斷處理一些事件,那麼設置一個Run Loop是最好的處理方式,如果需要Timer,那麼Run Loop就是必須的。
 
開發中遇到的需要使用Run Loop的情況有:
需要使用Port或者自定義Input Source與其他線程進行通訊。
子線程中使用了定時器
使用任何perform mSelector*****到子線程中運行方法
使用子線程去執行週期性任務
NSURLConnection在子線程中發起異步請求
 
 10OC中創建線程的方法是什麼?如果在主線程中執行代碼,方法是什麼
線程創建有三種方法:使用NSThread創建、使用 GCDdispatch、使用子類化的 NSOperation,然後將其加入NSOperationQueue;在主線程執行代碼,方法是performSelectorOnMainThread,如果想延時執行代碼可以用performSelector:onThread:withObject:waitUntilDone:
 
11)線程和進程的區別和聯繫
進程和線程都是由操作系統所體會的程序運行的基本單元,系統利用該基本單元實現系統對應用的併發性。 
 
進程和線程的主要差別在於它們是不同的操作系統資源管理方式。進程有獨立的地址空間,一個進程崩潰後,在保護模式下不會對其它進程產生影響,而線程只是一個進程中的不同執行路徑。線程有自己的堆棧和局部變量,但線程之間沒有單獨的地址空間,一個線程死掉就等於整個進程死掉,所以多進程的程序要比多線程的程序健壯,但在進程切換時,耗費資源較大,效率要差一些。但對於一些要求同時進行並且又要共享某些變量的併發操作,只能用線程,不能用進程
 
 
9.在項目什麼時候選擇使用GCD,什麼時候選擇NSOperation 
 
gcd是基於c的底層apiNSOperation屬於object-c類。
相對於gcd
1NSOperation擁有更多的函數可用,具體查看api
2,在NSOperationQueue中,可以建立各個NSOperation之間的依賴關係。
3,有kvo,可以監測operation是否正在執行(isExecuted)、是否結束(isFinished),是否取消(isCanceld)。
4NSOperationQueue可以方便的管理併發、NSOperation之間的優先級。
gcd主要與block結合使用。
 
項目中使用NSOperation的優點是NSOperation是對線程的高度抽象,在項目中使用它,會使項目的程序結構更好,子類化NSOperation的設計思路,是具有面向對象的優點(複用、封裝),使得實現是多線程支持,而接口簡單,建議在複雜項目中使用。
項目中使用GCD的優點是GCD本身非常簡單、易用,對於不復雜的多線程操作,會節省代碼量,而Block參數的使用,會是代碼更爲易讀,建議在簡單項目中使用。

 
1、線程的堆棧大小
 
iPhone設備上的應用程序開發也是屬於嵌入式設備的開發,同樣需要注意嵌入式設備開發時的幾點問題,比如資源上限,處理器速度等。
iPhone 中的線程應用並不是無節制的,官方給出的資料顯示iPhone OS下的主線程的堆棧大小是1M,第二個線程開始都是512KB。並且該值不能通過編譯器開關或線程API函數來更改。
 
2Autorelease
如果你什麼都不考慮,在線程函數內調用 autorelease,會出現錯誤
 
3、子線程中描畫窗口
多線程編程中普遍遵循一個原則,就是一切與UI相關的操作都有主線程做,子線程只負責事務,數據方面的處理。那麼如果想在子線程中更新UI時怎麼做呢?如果是在windows下,你會 PostMessage 一個描畫更新的消息,在iPhone中,需要使用performSelectorOnMainThread 委託主線程處理。
 
總結:
多線程能適當提高程序的執行效率,能適當提高資源利用率(CPU、內存利用率),但是開啓線程需要佔用一定的內存空間(默認情況下,主線程佔用1M,子線程佔用512KB),如果開啓大量的線程,會佔用大量的內存空間,降低程序的性能,而且線程越多,CPU在調度線程上的開銷就越大,使用多線程程序設計更加複雜:比如線程之間的通信、多線程的數據共享
 
一個iOS程序運行後,默認會開啓1條線程,稱爲“主線程”或“UI線程”
主線程的使用注意:別將比較耗時的操作放到主線程中。耗時操作會卡住主線程,嚴重影響UI的流暢度,給用戶一種“卡”的壞體驗
25. 線程是什麼?進程是什麼?二者有什麼區別和聯繫? UI第二十二講 多線程編程)
線程是CPU獨立運行和獨立調度的基本單位(可以理解爲一個進程中執行的代碼片段),進程是資源分配的基本單位(進程是一塊包含了某些資源的內存區域)。進程是線程的容器,真正完成代碼執行的是線程,而進程則作爲線程的執行環境。一個程序至少包含一個進程,一個進程至少包含一個線程,一個進程中的多個線程共享當前進程所擁有的資源。
 
26.談談你對多線程開發的理解?ios中有幾種實現多線程的方法?(UI第二十二講 多線程編程)
好處:
①、使用線程可以把程序中佔據時間長的任務放到後臺去處理,如圖片、視頻的下載
②、發揮多核處理器的優勢,併發執行讓系統運行的更快、更流暢,用戶體驗更好
缺點:
①、大量的線程降低代碼的可讀性,
②、更多的線程需要更多的內存空間
③、當多個線程對同一個資源出現爭奪的時候要注意線程安全的問題。
iOS有三種多線程編程的技術:
①、NSThread(兩種創建方式)
[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:^{
//這個block語句塊在子線程中執行

③、Grand Central Dispatch (GCD)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // 耗時的操作
    dispatch_async(dispatch_get_main_queue(), ^{
        // 更新界面
    });
});

PS:不顯示的創建線程的方法:
NSObject的類方法 performSelectorInBackground:withObject:
創建一個線程:
[Obj performSelectorInBackground:@selector(doSomething) withObject:nil];
 
 
27.線程同步和異步的區別?IOS中如何實現多線程的同步?
同步:一個線程要等待上一個線程執行完之後才能執行當前的線程,生活中的例子(上廁所)。
異步:同時去做兩件或者多件事。比如邊聽歌邊看報。
.runloop和線程有什麼關係?
總的說來,Run loop,正如其名,loop表示某種循環,和run放在一起就表示一直在運行着的循環。實際上,run loop和線程是緊密相連的,可以這樣說run loop是爲了線程而生,沒有線程,它就沒有存在的必要。Run loops是線程的基礎架構部分, Cocoa CoreFundation 都提供了 run loop 對象方便配置和管理線程的 run loop (以下都以 Cocoa 爲例)。每個線程,包括程序的主線程( main thread )都有與之相應的 run loop 對象。
runloop 和線程的關係:主線程的run loop默認是啓動的。iOS的應用程序裏面,程序啓動後會有一個如下的main()函數
int main(int argc, char * argv[]) {
@autoreleasepool {
         return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
重點是UIApplicationMain()函數,這個方法會爲main thread設置一個NSRunLoop對象,這就解釋了:爲什麼我們的應用可以在無人操作的時候休息,需要讓它幹活的時候又能立馬響應。
對其它線程來說,run loop默認是沒有啓動的,如果你需要更多的線程交互則可以手動配置和啓動,如果線程只是去執行一個長時間的已確定的任務則不需要。
在任何一個 Cocoa 程序的線程中,都可以通過以下代碼來獲取到當前線程的 run loop
NSRunLoop *runloop = [NSRunLoop currentRunLoop];
51. GCD的隊列(dispatch_queue_t)分哪兩種類型?
串行隊列Serial Dispatch Queue
並行隊列Concurrent Dispatch Queue
77. 你參與的APP,是如何處理多個服務的同步發起的?
使用iOS線程技術,創建並行隊列來分別執行不同的任務。將不同的任務加入到子隊列當中,任務執行後回到主線程當中刷新UI界面。
APP 界面一般都是根據產品需求和UI效果圖來完成的,但是我們爲了提高代碼的複用性,會將視圖的實現進行封裝,然後在控制器當中進行加載調用
88.NSOperationQueue有哪些使用方式?
一種在iOS中執行併發操作的方法,是使用NSOperationNSOperationQueue類。在本教程中,你將學習如何使用它們!你會先創建一款不使用多線程的app,這樣它會變得響應非常遲鈍。然後改進程序,添加上並行操作–並且希望–可以提供一個交互響應更好的界面給用戶!
另一種處理操作之間的依賴關係,如果操作直接有依賴關係,比如第二個操作必須等第一個操作結束後再執行。控制線程池中的線程數
89.NSThread中的Runloop的作用,如何使用?
有些情況下,我們還是在運行一些長線任務或者複雜任務的時候需要用比較原始的NSThread。這就需要爲NSThread創建一個run loop.
         1       NSThread *thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(playerThread: ) object:nil];  
         2       [thread start];  
         3       //如果要利用NSOperation,原理類似。只需要加入到queue裏面去就好了。。queue會在合適的時機調用方法,下面代碼作爲參考。 
         4       - (void) playerThread: (void*)unused   
         5       {   
         6       audioRunLoop = CFRunLoopGetCurrent();//子線程的runloop引用 
         7       NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];//子線程的  
         8       [self initPlayer]; CFRunLoopRun(); //運行子線程的  
         9       [pool release];  // run loop,這裏就會停住了。
         10     }  
         11      // 實現一個timer,用於檢查子線程的工作狀態,並在合適的時候做任務切換。或者是合適的時候停掉自己的
 
         12      -(void) initPlayer {   
         13      // 在這裏你可以初始化一個工作類,比如聲音或者視頻播放   
         14      NSTimer *stateChange = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:  
         15        @selector(checkStatuserInfo:nil repeats:YES];  
         16      }  
         17      -(void) checkState:(NSTimer*) timer   
         18      {   
         19      if(需要退出自線程了) {  
         20      //釋放子線程裏面的資源  
         21      CFRunLoopStop( CFRunLoopGetCurrent());//結束子線程任務  
         22      }   
         23      } 
3. NSThreadNSOperationQueue以及GCD等多線程編程技術什麼情況下使用?
 
1NSThread
優點:NSThread 比其他兩個輕量級
缺點:需要自己管理線程的生命週期,線程同步。線程同步對數據的加鎖會有一定的系統開銷
 

2Cocoa  NSOperation
優點:不需要關心線程管理, 數據同步的事情,可以把精力放在自己需要執行的操作上。
Cocoa operation相關的類是NSOperation, NSOperationQueue.
NSOperation是個抽象類,使用它必須用它的子類,可以實現它或者使用它定義好的兩個子類: NSInvocationOperationNSBlockOperation.
創建NSOperation子類的對象,把對象添加到NSOperationQueue隊列裏執行。
2GCD使用過程中遇到的問題?
 
44.項目中哪塊用到多線程,碰到了什麼問題,怎麼解決的
 
什麼時候使用多線程:
將耗時、輪詢或者併發需求高等任務分配到其他線程執行,並由主線程負責統一更新界面會使得應用程序更加流暢,用戶體驗更好,例如網絡請求,播放遊戲的背景音樂,文件下載等。
 
碰到的問題以及解決辦法:
1)使用多線程時通常需要控制線程的併發數,因爲線程會消耗系統資源,同時運行的線程過多,系統會變慢
使用以下方法可以控制併發的線程數量:
-(void)setMaxConcurrentOperationCount:(NSInteger)cnt;
使用addDependency可以建立操作之間的依賴關係,設定操作的執行順序
2)當多個線程對同一個資源出現爭奪的時候需要注意線程安全問題
3)更新UI界面,處理界面和用戶之間的交互事件一定要在主線程中處理。
‘多線程中棧與堆是公有的還是私有的
一般來說棧是私有的,堆是公有的;但是可以爲特定的線程創建私有的堆
 
在多線程環境下,每個線程擁有一個棧和一個程序計數器。棧和程序計數器用來保存線程的執行歷史和線程的執行狀態,是線程私有的資源。其他的資源(比如堆、地址空間、全局變量)是由同一個進程內的多個線程共享。
 
堆: 是大家共有的空間,分全局堆和局部堆。全局堆就是所有沒有分配的空間,局部堆就是用戶分配的空間。堆在操作系統對進程初始化的時候分配,運行過程中也可以向系統要額外的堆,但是記得用完了要還給操作系統,要不然就是內存泄漏。
棧:是個線程獨有的,保存其運行狀態和局部自動變量的。棧在線程開始的時候初始化,每個線程的棧互相獨立,因此,棧是 thread safe的。操作系統在切換線程的時候會自動的切換棧,就是切換 SS/ESP寄存器。棧空間不需要在高級語言裏面顯式的分配和釋放。
 
24、描述runloop和線程的關係
Run loop,正如其名,loop表⽰示某種循環,和run放在⼀一起就表⽰示⼀一直在運⾏行着 的循環。實際上,run loop和線程是緊密相連的,可以這樣說run loop是爲了線 程⽽而⽣生,沒有線程,它就沒有存在的必要。Run loops是線程的基礎架構部分, Cocoa和CoreFundation都提供了run loop對象⽅方便配置和管理線程的run loop(以
下都已Cocoa爲例)。每個線程,包括程序的主線程(main thread)都有與之相 應的run loop對象。
 
8、GCD的隊列(dispatch_queue_t)分哪兩種類型?編寫代碼:使⽤用並⾏行隊列 實現多線程開發
串⾏行隊列Serial Dispatch Queue
並⾏行隊列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);
  
5、列舉幾種進程的同步機制並進行比較。
 
(1)信號量機制    一個信號量只能置一次初值,以後只能對之進行p操作或v操作。由此也可以看到,信號量機制必須有公共內存,不能用於分佈式操作系統,這是它最大的弱點。信號量機制功能強大,但使用時對信號量的操作分散, 而且難以控制,讀寫和維護都很困難。加重了程序員的編碼負擔;核心操作P-V分散在各用戶程序的代碼中,不易控制和管理;一旦錯誤,後果嚴重,且不易發現和糾正。
(2)自旋鎖  旋鎖是爲了保護共享資源提出的一種鎖機制。調用者申請的資源如果被佔用,即自旋鎖被已經被別的執行單元保持,則調用者一直循環在那裏看是否該自旋鎖的保持着已經釋放了鎖。自旋鎖是一種比較低級的保護數據結構和代碼片段的原始方式,可能會引起以下兩個問題; 1、死鎖 2、過多地佔用CPU資源 傳統自旋鎖由於無序競爭會導致“公平性”問題  
(3)管程  信號量機制功能強大,但使用時對信號量的操作分散,而且難以控制,讀寫和維護都很困難。因此後來又提出了一種集中式同步進程——管程。其基本思想是將共享變量和對它們的操作集中在一個模塊中,操作系統或併發程序就由這樣的模塊構成。這樣模塊之間聯繫清晰,便於維護和修改,易於保證正確性。
(4)會合 進程直接進行相互作用
(5)分佈式系統 由於在分佈式操作系統中沒有公共內存,因此參數全爲值參,而且不可爲指針。
 
 
6、導致進程死鎖的原因是什麼,如何解決。
產生死鎖的原因:一是系統提供的資源數量有限,不能滿足每個進程的使用;二是多道程序運行時,進程推進順序不合理。
產生死鎖的必要條件是:1、互斥條件;2、不可剝奪條件(不可搶佔);
3、部分分配;4、循環等待。
根據產生死鎖的四個必要條件,只要使其中之一不能成立,死鎖就不會出現。爲此,可以採取下列三種預防措施:
1、採用資源靜態分配策略,破壞"部分分配"條件;
2、允許進程剝奪使用其他進程佔有的資源,從而破壞"不可剝奪"條件;
3、採用資源有序分配法,破壞"環路"條件。
死鎖的避免不嚴格地限制死鎖的必要條件的存在,而是系統在系統運行過程中小心地避免死鎖的最終發生。最著名的死鎖避免算法是銀行家算法。死鎖避免算法需要很大的系統開銷。
解決死鎖的另一條途徑是死鎖檢測方法,這種方法對資源的分配不加限制,即允許死鎖的發生。但系統定時地運行一個"死鎖檢測"程序,判斷系統是否已發生死鎖,若檢測到死鎖發生則設法加以解除。
 
解除死鎖常常採用下面兩種方法:1、資源剝奪法;2、撤消進程法
解決策略:鴕鳥策略、預防策略、避免策略、檢測與解除死鎖
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章