首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > Iphone >

如何等待一个线程结束

2012-12-30 
怎么等待一个线程结束在cocoa下不知道怎么实现等待一个线程结束.超级怀念windows的WaitForSingle函数.下面

怎么等待一个线程结束
在cocoa下不知道怎么实现等待一个线程结束.
超级怀念windows的WaitForSingle函数.
下面window下一个包装,有谁可以翻译成mac的功能?



#pragma once

#include <windows.h>

#define INVALID_PRIORITY -88888888

class thread {
public:
thread(): hThread(0) {
hRequestEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
}
virtual ~thread() {
stop();
CloseHandle(hRequestEvent);
}

//set thread name, that's usually invoked in the OnExecute of subclass
void named(const char* name) { //fixed by rene/2012-05-21
typedef struct tagTHREADNAME_INFO {
DWORD dwType;     //must be 0x1000
LPCSTR szName;    //pointer to name (in user addr space)
DWORD dwThreadID; //thread ID (-1=caller thread)
DWORD dwFlags;    //reserved for future use, must be zero
} THREADNAME_INFO;

THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = name;
info.dwThreadID = -1;
info.dwFlags = 0;

__try {
RaiseException(0x406D1388, 0, sizeof(info) / sizeof(DWORD), (const DWORD*)&info);
}
__except(EXCEPTION_CONTINUE_EXECUTION) {}
}

bool start() {
stop();
ResetEvent(hRequestEvent);

DWORD dwThreadId;
hThread = CreateThread(NULL, 0, ThreadProc, this, 0, &dwThreadId);

return true;
}

//stop thread safely, suggest.
bool stop() { //fixed by rene/2012-04-24
SetEvent(hRequestEvent);
join();

if(hThread)
CloseHandle(hThread);
hThread = NULL;

return true;
}

//terminate thread violently, no suggest.
bool exit() { //fixed by rene/2012-05-22
TerminateThread(hThread, 0); //ExitThread(0);

if(hThread)
CloseHandle(hThread);
hThread = NULL;

return true;
}

bool join() {
DWORD exitCode;
if(GetExitCodeThread(hThread, &exitCode) && exitCode == STILL_ACTIVE) {
DWORD dwRet = 0;
MSG msg;

while(TRUE) {
//using MsgWaitForMultipleObjects instead of WaitForSingleObject.
//because of invoking SendMessage in thread.
//otherwise, it will block the thread.
dwRet = MsgWaitForMultipleObjects(1, &hThread, FALSE, INFINITE, QS_ALLINPUT); //fixed by rene/2012-04-05

if(dwRet == WAIT_OBJECT_0 + 1) {
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { //fixed by rene/2012-04-05
TranslateMessage(&msg);
DispatchMessage(&msg);
}
continue;
}
break;
}
}

return true;
}

bool pause() {
//if(hThread)
SuspendThread(hThread);
return true;
}

bool resume() {
//if(hThread)
ResumeThread(hThread);
return true;
}

/******************************************************


set the thread priority as below:
THREAD_PRIORITY_TIME_CRITICAL=15.  Indicates 3 points above normal priority.
THREAD_PRIORITY_HIGHEST=2.   Indicates 2 points above normal priority.
THREAD_PRIORITY_ABOVE_NORMAL=1.   Indicates 1 point above normal priority.
THREAD_PRIORITY_NORMAL=0.   Indicates normal priority.
THREAD_PRIORITY_BELOW_NORMAL=-1.  Indicates 1 point below normal priority.
THREAD_PRIORITY_LOWEST=-2.  Indicates 2 points below normal priority.
//THREAD_PRIORITY_ABOVE_IDLE=.    Indicates 3 points below normal priority.
THREAD_PRIORITY_IDLE=-15. Indicates 4 points below normal priority.
******************************************************/
bool setPriority(int priority) {
//if(hThread)
SetThreadPriority(hThread, priority);
return true;

}
int getPriority() {
if(!hThread) return INVALID_PRIORITY;
return GetThreadPriority(hThread);
}
protected:
HANDLE hRequestEvent;

virtual void OnExecute() = 0;
private:
HANDLE hThread;

static DWORD WINAPI ThreadProc(LPVOID lParam) {
thread* th = (thread*)lParam;
if(th)
th->OnExecute();
return 0;
}
};



------------------------------------
这个类用法如下:

class CThreadEx: public thread {
public:
CThreadEx(HWND wnd): m_wnd(wnd) {}
private:
HWND m_wnd;

void OnExecute() {
for(int i = 0; i < 20; i++) {
if(WaitForSingleObject(hRequestEvent, 0) != WAIT_TIMEOUT)
goto exit;

char buf[200] = {0};
sprintf(buf, "on thread msg---%d times", i);
::SendMessage(m_wnd, WM_THREAD_MSG, 0, (LPARAM)buf);

Sleep(1000);
}
exit:
return;
}
};

void test() {
thread* th = new CThreadEx(GetSafeHwnd());
th->start();
th->stop();
th->pause();
th->resume();

//some times, stop and free the thread
delete th;
}

[解决办法]
不了解的门外汉扔砖头:线程退出前发送个消息,咋样啊
[解决办法]
GCD,使用代码块。
[解决办法]
只要不是在主线程里,是不会影响UI

这句可以让你在后台线程中设置UI,使用block可以让你简化回调的过程
[myLabel performSelectorOnMainThread : @ selector(setText: ) withObject:@"this is my text" waitUntilDone:YES];

[解决办法]

pthread,去了解下这个。ios我记得是支持这个的。
[解决办法]
1.第一种方法,可以用 GCD中的  dispatch_async 的block ,楼主可以google
2.第二种方法,可在该thread的回调函数中,通知主线程或者其他线程。
3.可以用notification。
[解决办法]
JieCh121599

同意楼上的。。。

1.GCD 使用block 作用 回调函数(回调函数,一般是UI或者返回上层逻辑,如果是UI,确认在MainThread)


2.Thread  有一个这样的方法
 NSThread *a = nil;
    [a performSelectorOnMainThread:<#(SEL)#> withObject:<#(id)#> waitUntilDone:<#(BOOL)#>]

这个的意思是,Thread a的代码执行是加在 mainThrad runLoop的末端,当然也可以是
    [a performSelector:<#(SEL)#> onThread:<#(NSThread *)#> withObject:<#(id)#> waitUntilDone:<#(BOOL)#>]

3.发送通知。更新UI最好是返回到 mainThread的时候发送。

热点排行