假设创建线程的接口如下
/*
@param[in]:
char *pThreadName 线程名称
int nPriority 优先级
int nStackSize 线程栈空间
ThreadEntry fnThreadEntry 线程入口函数(函数指针)
void *pAry 入口函数的参数
@param[out]:
ThreadHandle 线程句柄
*/
ThreadHandle threadCreate(char *pThreadName, int nPriority, int nStackSize, ThreadEntry fnThreadEntry, void *pAry);
创建线程调用的过程可能如下:
int init(void)
{
HANDLE handle = creatHandle();//某个会生成句柄的函数
ThreadHandle threadHandle = threadCreate("myThreadName", 10, 10*1024, fnProcess, (void*)&handle);//创建线程,handle 句柄线程作为入口函数的参数
// do something
}
void fnProcess(void *pAry)
{
if(!pAry)
{
return;
}
HANDLE hCurHandle= * (HANDLE *)pAry;
//do something
}
发现创建线程时,传入的参数(void)&handle,与入口函数接收到的参数pAry是匹配的;但是强制转换后HANDLE hCurHandle= * (HANDLE *)pAry;得到的hCurHandle不等于传入的handle。
强制转换的前后地址都是对的,但是取值的结果不一样,遇到这个问题,刚开始以为是强制转换导致的,后面才往变量声明周期上考虑,HANDLE handle是一个栈变量,当函数 int init(void)执行完毕,该变量的内存空间会被销毁,因此创建线程时传入的(void*)&handle其实是一个野指针,导致void fnProcess(void *pAry)中得到的地址貌似是对的,实则地址上的内容不合法,也就是获取到不确定的错误句柄hCurHandle。
这个问题比较隐蔽,实则是老生常谈的变量生命周期的问题。
可以这样处理,创建线程时直接将 handle强转为 (void *)handle传入,线程处理函数接收到参数后直接强转为HANDLE hCurHandle= (HANDLE)pAry,这样得到的handle就是正确的了。












网友评论