最近想把公司的DLNA平台代码 (DMS DMP)移植到Windows平台。
考虑到对windows内核不熟悉,打算继续用POSIX API。
准备工作:
开发平台: WINXP + VS2008 + Phread for Win32 (http://www.sourceware.org/pthreads-win32/)
接口设计:
OS_TASK_Handle OS_TASK_Creat(
API_IN XPCHAR taskname, // 线程名称,Debug用
API_IN OS_TASK_Func pFunc, // 任务函数
API_IN void *userData, // 用户数据
API_IN xuint stackSize // 栈空间大小
);
OS_RET OS_TASK_Start(
API_IN OS_TASK_Handle handle
);
OS_RET OS_TASK_Stop(
API_IN OS_TASK_Handle handle
);
OS_RET OS_TASK_StopWithCond(
API_IN OS_TASK_Handle handle,
API_IN void* pCond // 结束条件
);
XBOOL OS_TASK_IsRunable(
API_IN OS_TASK_Handle handle
);
OS_RET OS_TASK_Destroy(
API_IN OS_TASK_Handle handle
);
void * OS_TASK_GetUserData( // 主要用于任务函数中获取用户数据
API_IN OS_TASK_Handle handle
);
实现探讨:
1 OS_TASK_Start
pthread_attr_t thread_attr;
pthread_attr_init(&thread_attr);
pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); // 采用分离模式, 默认是PTHREAD _CREATE_JOINABLE
pthread_attr_setstacksize (&thread_attr,pTaskHandle->stackSize); // 设置Stack 大小。
if (pthread_create(&pTaskInfo->pThread, &thread_attr, PosixThreadProc, pTaskHandle) != 0) { // pTaskHandle 是OS_TASK_Handle的实现封装
pTaskHandle->runnableFlag = XFALSE;
pthread_attr_destroy(&thread_attr);
return S_FAILURE;
}
pthread_attr_destroy(&thread_attr);
pTaskHandle->runnableFlag = XTRUE;
PosixThreadProc函数实现:
由于Phread for Win32 下载版本不支持Signal,为了简单,只能把linxu版本的设置信号相关代码删除。
#if ndef WIN32
sigfillset(&set);
sigdelset(&set, SIGQUIT);
pthread_sigmask(SIG_SETMASK, &set, NULL);
memset(&actions, 0, sizeof(actions));
sigemptyset(&actions.sa_mask);
actions.sa_flags = 0;
actions.sa_handler = sig_handler;
sigaction(SIGQUIT, &actions, NULL);
#endif
pthread_once(&xos_thread_mykeycreated, xos_thread_createkey); //一次性初始化
pthread_setspecific(xos_thread_self_ref, param);
if (thread->action != NULL)
thread->action(thread);
2 OS_TASK_StopWithCond
先判断线程状态,如果已经启动,则发送SIGNAL,并调用pthread_kill结束线程。为了安全,再睡眠一段时间。
if (pTaskHandle->runnableFlag == XTRUE) {
pTaskHandle->runnableFlag = XFALSE;
if (pCond != NULL) {
OS_Cond_Signal((OS_Cond_Handle)pCond);
}
XLOG_Debug_L4("Killing thread %p\n", pTaskInfo->pThread);
#ifdef WIN32
pthread_kill(pTaskInfo->pThread, 0);
#else
pthread_kill(pTaskInfo->pThread, SIGQUIT);
#endif