在cocoa下不知道怎么实现等待一个线程结束.
超级怀念windows的WaitForSingle函数.
下面window下一个包装,有谁可以翻译成mac的功能?
#pragma once#include <windows.h>#define INVALID_PRIORITY -88888888class 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;
}
超级怀念windows的WaitForSingle函数.
下面window下一个包装,有谁可以翻译成mac的功能?
#pragma once#include <windows.h>#define INVALID_PRIORITY -88888888class 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;
}
它在windows下的原理是:不断查询thread句柄是否存在.
但是在cocoa下杯具了
th->start();
th->join(); printf("hello world!");
你那个做法能够在线程退出时,主动告诉外部环境:"我要退出了"
仍然谢谢你..不过我要的效果是:
在上面的代面中,
添加了th->join();
之后的代码,如printf("hello world!");
等等.
要在线程完成之后才运行.
--------------------
最好是在线程等待时,还不影响主界面消息,事件的分发.
就是说,我在等待线程结束时,
界面还是允许响应单击,鼠标,拖动等等在windows中为
[code=c][
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;
}
/code]
[myLabel performSelectorOnMainThread : @ selector(setText: ) withObject:@"this is my text" waitUntilDone:YES];
pthread,去了解下这个。ios我记得是支持这个的。
2.第二种方法,可在该thread的回调函数中,通知主线程或者其他线程。
3.可以用notification。
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的时候发送。
pthread_join();确实能等待线程结束,但他没有分发事件的功能.....例如,以下,在join处不能处理鼠标等其他事件.
pthread_create();
pthread_start();
pthread_join();
//do others
#include <pthread.h>class thread {
public:
thread() {
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutex_init(&hRequestEvent, &attr);
pthread_mutexattr_destroy(&attr);
}
virtual ~thread() {
stop();
pthread_mutex_destroy(&hRequestEvent);
}
void named(const char* name) {
}
bool start() {
stop();
pthread_mutex_lock(&hRequestEvent);
//Create the thread using POSIX routines.
//pthread_attr_t attr;
//pthread_attr_init(&attr);
//pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
//pthread_create(&hThread, &attr, &ThreadProc, this);
//pthread_attr_destroy(&attr);
pthread_create(&hThread, NULL, &ThreadProc, this); //PTHREAD_CREATE_JOINABLE by default
return true;
}
//stop thread safely, suggest.
bool stop() {
pthread_mutex_unlock(&hRequestEvent);
join();
pthread_detach(hThread); //allow thread to be release once fall into stoped state
return true;
}
bool isStoped() { //added by rene/2012-11-21
return !pthread_mutex_trylock(&hRequestEvent);
}
//terminate thread violently, no suggest.
bool exit() {
pthread_cancel(hThread); //>>??线程被回收后,ID可能指向另一个线程,此时可能取消的是另一个线程,而不是返回ESRCH错误码
pthread_detach(hThread); //allow thread to be release once fall into stoped state
return true;
}
bool join() {
//pthread_join(hThread, NULL);
return true;
}
bool pause() {
return true;
}
bool resume() {
return true;
}
bool setPriority(int priority) {
return true;
}
int getPriority() {
return -1;
}
protected:
pthread_mutex_t hRequestEvent;
virtual void OnExecute() = 0;
private:
pthread_t hThread;
static void* ThreadProc(void* lParam) {
thread* th = (thread*)lParam;
if(th)
th->OnExecute();
return 0;
}
};
-------------
安全退出线程已经完成....
join时,响应其他鼠标等事件的功能还不行.....