多執行緒的使用與注意事項

2021-06-06 17:06:51 字數 3960 閱讀 5162

多執行緒程式的控制模型可以參考這裡,一般情況下都是使用 管理者/工人模型, 這裡,我們使用iphone sdk中的 nsthread 來實現它。

接下來,在 tutorialprojectviewcontroller.h 檔案中建立各個ui控制項的 iboutlets.

123

4567

891011

1213

1415

@inte***ce

tutorialprojectviewcontroller : uiviewcontroller

同時,也需要建立outlets變數的property.

123

4

@property (nonatomic, retain) iboutlet uilabel *threadvaluelabel;

@property (nonatomic, retain) iboutlet uiprogressview *threadprogressview;

@property (nonatomic, retain) iboutlet uiprogressview *threadstartbutton;

@property (nonatomic, retain) iboutlet uilabel *testvaluelabel;

接下來定義按鈕按下時的動作函式,以及slider的變化函式。

1

2

- (ibaction) startthreadbuttonpressed:(uibutton *)sender;

- (ibaction) testvaluesliderchanged:(uislider *)sender;

然後在 tutorialprojectviewcontroller.m 檔案中synthesize outlets,並在檔案為實現dealloc釋放資源。

123

4567

891011

1213

1415

1617

18

@synthesize

threadvaluelabel, threadprogressview, testvaluelabel, threadstartbutton;

...- (void)dealloc

現在開始執行緒部分的**,首先當 thread button 被按下的時候,建立新的執行緒.

123456

- (ibaction) startthreadbuttonpressed:(uibutton *)sender
該按鈕被按下後,隱藏按鈕以禁止多次建立執行緒。然後初始化顯示值和進度條,最後建立新的執行緒,執行緒的函式為 startthebackgroundjob.

具體的 startthebackgroundjob 函式定義如下.

123

4567

89

- (void)startthebackgroundjob
最後一行,阻塞呼叫(waituntildone狀態是on)函式 makemyprogressbarmoving。

123

4567

891011

- (void)makemyprogressbarmoving 

else threadstartbutton.hidden = no;

}

這裡計算用於顯示的進度條的值,利用 nstimer ,每0.5秒自增0.01,當值等於1的時候,進度條為100%,退出函式並顯示剛才被隱藏的按鈕。

最後,新增 uislider 的實現函式,用來更改主線程中 test part 中的 label 值。

123

45

- (ibaction) testvaluesliderchanged:(uislider *)sender
編譯執行,按下執行緒開始按鈕,你將看到進度條的計算是在後台執行。

執行緒的堆疊大小

iphone裝置上的應用程式開發也是屬於嵌入式裝置的開發,同樣需要注意嵌入式裝置開發時的幾點問題,比如資源上限,處理器速度等。

你可以用下面的例子測試你的裝置,這裡使用posix thread(pthread),裝置環境是 iphone 3gs(16gb)、sdk是3.1.3。

123

4567

891011

1213

1415

1617

1819

2021

2223

24

#include

"pthread.h"

void *threadfunc(void *arg)

void* stack_base = pthread_get_stackaddr_np(pthread_self());

size_t

stack_size = pthread_get_stacksize_np(pthread_self());

struct

rlimit

limit;

getrlimit(rlimit_stack, &limit);

nslog(@"main thread: base:%p / size:%u", stack_base, stack_size);

nslog(@" rlimit-> soft:%llu / hard:%llu", limit.rlim_cur, limit.rlim_max);

pthread_t

thread;

pthread_create(&thread, null, threadfunc, null);

// [window addsubview:viewcontroller.view];

[window makekeyandvisible];

}

結果如下:

模擬器

main thread: base:0xc0000000 / size:524288

rlimit-> soft:8388608 / hard:67104768

thread: base:0xb014b000 / size:524288

裝置

main thread: base:0x30000000 / size:524288

rlimit-> soft:1044480 / hard:1044480

thread: base:0xf1000 / size:524288

由此可見,當你測試多執行緒的程式時,模擬器和實際裝置的堆疊大小是不一樣的。如果有大量遞迴函式呼叫可要注意了。

autorelease

nsautoreleasenopool(): object 0x********* of class nsconretedata autoreleased with no pool in place ….
1
nsautoreleasepool *pool = [[nsautoreleasepool alloc]init];
子執行緒中描畫視窗

多執行緒程式設計中普遍遵循乙個原則,就是一切與ui相關的操作都有主線程做,子執行緒只負責事務,資料方面的處理。那麼如果想在子執行緒中更新ui時怎麼做呢?如果是在windows下,你會 postmessage 乙個描畫更新的訊息,在iphone中,需要使用performselectoronmainthread 委託主線程處理。

1
imageview.image = [uiimage imagenamed:@"hoge.png"];
這麼做,什麼也不會出現的。需要將該處理委託給主線程來做,像下面:

1
[delegate performselectoronmainthread:@selector(theprocess:) withobject:nil waituntildone:yes];
就ok了!

多執行緒的使用與注意事項

多執行緒的使用與注意事項 從例子入手 多執行緒程式的控制模型可以參考 url 這裡 url 一般情況下都是使用 管理者 工人模型,這裡,我們使用iphone sdk中的 nsthread 來實現它。img 接下來,在 tutorialprojectviewcontroller.h 檔案中建立各個ui...

多執行緒使用注意事項

在開發過程中經常使用到多執行緒。對ios的多執行緒有很多不解的地方,這裡暫且記錄下來。具體原因有待以後慢慢研究。void scanloop pool release 以asyncudpsocket物件為引數的處理函式,如下所示 void processipscanwithsocket asyncud...

多執行緒程式設計注意事項

1 明確目的,為什麼要使用多執行緒?如果是由於單執行緒讀寫或者網路訪問 例如http訪問網際網路 的瓶頸,可以考慮使用執行緒池。如果是對不同的資源 例如socket連線 進行管理,可以考慮多個執行緒。2 執行緒使用中要注意,如何控制線程的排程和阻塞,例如利用事件的觸發來控制線程的排程和阻塞,也有用訊...