iOS多線程開發(二)---線程管理

來源:互聯網
上載者:User

標籤:

 

線程管理

       線程管理組件括建立,配置,退出三部分。主要包括建立線程的成本,線程建立,線程屬性配置,線程主體入口函數編寫,線程中斷等 一,線程建立成本      1,為輔助線程分配的堆棧空間大小,便於系統和進程管理,以及為函數參數和局部變數分配空間        A,核心資料結構(kernel data structures)---大約1KB,This memory is used to store the thread data structures and attributes, much of which is allocated as wired memory and therefore cannot  be        B,堆棧空間(Stack Space)---512 KB(secondary threads)/8 MB (Mac OS X main thread)/1 MB (iOS main thread) ,The minimum allowed stack size for secondary threads is 16 KB and the stack size must be a multiple of 4 KB. The space for this memory is set aside in your process space at thread creation time, but the actual pages associated with that memory are not created until they are need       2,建立線程需要的時間成本---大約90ms,建立時間依賴於處理器的負載,計算速度,和可用的系統和程式空間i二,建立線程       建立線程需要做三部分工作:主體進入點,可用線程(用以啟動被建立的線程),線程的屬性配置。建立線程有很多方法,比如NSThread,POSIX,NSObject,及其他方法(Multiprocessing Services)等      1,使用NSThread建立線程        A,[NSThread detachNewThreadSelector:@selector(myThreadMainMethod:) toTarget:self withObject:nil];          線程的主體進入點是myThreadMainMethod,可用線程是self存在的線程,不過這個線程的屬性不能線上程建立前配置,只能線上程內配置        B,建立一個新的NSThread執行個體,然後調用他的start方法啟動線程              NSThread  *myThread = [[NSThread alloc] initWithTarget:self selector:@selector(myThreadMainMethod) withObject:nil];              [myThread start]; // Actually create the thread         線程主體入口是myThreadMainMethod,可用線程是self存在的線程,線程屬性可以在建立一個新的NSThread執行個體之後,start方法調用之前設定 註:通過NSThread建立的線程,主要通過performSelector:onThread:withObject:withUntilDone方法進行線程間通訊比較便捷的方法之一。      2,使用POSIX建立線程        A,Creating a thread in C#include <assert.h> #include <pthread.h>   void* PosixThreadMainRoutine(void* data){     // DO Some Work here     ......     return NULL}  void  LaunchThread(){ // Create the thread using POSIX routines.

pthread_attr_t attr;

pthread_t  posixThreadID; int returnVal;    returnVal =  pthread_attr_init(&attr); assert(!returnVal);  returnVal = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); assert(!returnVal);  int threadError = pthread_create(&posixThreadID, &attr, &PosixThreadMainRoutine, NULL); returnVal = pthread_attr_destroy(&attr); assert(!returnVal); if (threadError != 0)  { // Report an error. }} 在上面的代碼裡,線程主體進入點是PosixThreadMainRoutine,通過pthread_create建立線程,在建立線程前初始化及配置線程屬性pthread_attr_init/pthread_attr_setdetachstate註:基於C語言的應用程式,常用的線程間通訊包括使用連接埠(ports),條件(conditions)和共用記憶體(shared memory)      3,使用NSObject建立線程 [myObj performSelectorInBackground:@selector(doSomething) withObject:nil];參照NSThread方法建立線程      4,使用其他技術建立線程 唯一一個可以考慮使用的是多處理 服務(Multiprocessing Services),它本身就是在 POSIX 線程上執行      5,在Cocoa程式裡使用POSIX線程,需要注意的問題        A,Cocoa架構的保護            對於多線程應用程式,Cocoa架構使用鎖和其他同步方式保證代碼的正確使用。但是為了避免因為這些鎖造成的單線程下的效能損失,Cocoa架構直到應用程式建立NSThread類產生它的第一個新線程的時候才建立這些鎖。如果僅用POSIX建立新的線程,那麼Cocoa架構將不會自動建立這些保護同步的鎖。這樣有可能因為這些造成Cocoa崩潰。解決辦法:在建立第一個新線程之前,使用NSThread類產生一個線程,並讓他立刻退出。這樣保證Cocoa架構所需要的鎖到位。        B,混合POSIX和Cocoa的鎖 在同一應用程式裡面可以混合使用POSIX和Cocoa的鎖,因為Cocoa的鎖和條件對象基本上只是封裝POSIX的互斥體和條件。但是兩者不能交叉使用,Cocoa的NSLock調用POSIX建立的mutex對象,反之依然三,配置線程屬性 線程屬性主要包括線程的堆棧大小,本機存放區,線程的脫離狀態(detached),線程的優先順序      1,配置線程的堆棧大小 A,Cocoa線程,只有通過New NSThread類的方法建立的線程才能配置線程的堆棧大小 [myThread setStackSize]; B,POSIX線程,建立一個限的pthread_attr_t資料結構,使用pthread_attr_setstacksize函數設定線程堆棧大小      2,配置執行緒區域儲存---每個線程都維護一個鍵-值的字典結構,如何設定和訪問這個結構呢? A,Cocoa線程,NSMutableDictionary *mDict = [[NSThread currentThread] threadDictionary]; B,POSIX線程,通過pthread_setspecific設定這個結構,通過pthread_getspicific訪問這個結構      3,設定線程的脫離狀態 脫離線程(Detach Thread)---線程完成後,系統自動釋放它所佔用的記憶體空間 可連接線程(Joinable Thread)---一線程完成後,不回收可連接線程的資源 在應用程式退出時,脫離線程可以立即被中斷,而可連接線程則不可以。每個可串連 線程必須在進程被允許可以退出的時候被串連。所以當線程處於周期性工作而不允許被中斷的時 候,比如儲存資料到硬碟,可連接線程是最佳選擇。 如果你想要建立可連接線程,唯一的辦法是使用 POSIX 線程。POSIX 預設建立的 線程是可串連的。通過pthread_attr_setdetachstate函數設定是否脫離屬性      4,線程的優先順序 A,Cocoa線程,[NSThread setThreadPriority];設定線程的優先順序 B,POSIX線程,pthread_setschedparam函數實現優先順序設定註:高低線程互動時,要注意因為低線程的饑餓狀態造成的阻塞,造成效能瓶頸,影響應用程式效能。四,線程主體入口函數 線上程主體入口函數裡面,主要做三個工作: 1,建立一個自動釋放池(Autorelease pool),注意:要經常主動清理自動釋放池裡面的記憶體,提高線程的記憶體空間 2,設定異常處理 添加try/catch模組,捕獲任何未知的異常,並提供適當的響應 3,設定一個run loop 對於需要動態處理到來的工作要求的線程,需要給線程添加一個run loop五,中斷線程 中斷線程要注意的是,儘力保證線程從主體入口函數裡面退出,這樣能夠保證線程的資源被自動釋放。- (void)threadMainRoutine{ Bool moreWorkToDo = YES; Bool exitNow  = NO; NSRunLoop *runLoop = [NSRunLoop currentRunLoop];  // Add the exitNow BOOL to the thread dictionary NSMutableDictionary *threadDict = [[NSThread currentThread] threadDictionary]; [threadDict setValue:[NSNumber numberWithBool:exitNow] forKey:@"ThreadShouldExitNow"];  // install an input method [self myInstallCustomInputSource];  while(moreWorkToDo && !exitNow) { // Do one chunk of a larger body of work here // change the value of the moreWorkToDo Boolean when Done  // Run the run loop but timeout immediately if the input source isn‘t waiting to fire [runLoop runUntilDoneDate:[NSDate date]];  // check the see if an input source handle changed  the exitNow value. exitNow = [[threadDict valueForKey:@"ThreadShouldExitNow"] boolValue]; }}

iOS多線程開發(二)---線程管理

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.