今天遇到一个问题,gdb执行程序完全没有问题,但直接执行就会段错误,百思不得其解,各种纠结,各种搜索引擎都试了一遍,无果!后来问题还是被我自己挖出来了。
看下边一段代码:
int TaskSendControl()
{
pthread_t prov_thread[CLIENT_NUM];
int prov[CLIENT_NUM];
for(int i=0; i< CLIENT_NUM; i++)
{
prov[i] = i;
if( pthread_create(&prov_thread[i], NULL, ProvTaskSend, (void*)&prov[i] ) != 0 )
{
cout << "TaskSendControl" << endl;
gv_alert.InsertAlert(MAIN,1,gv_LocalName,gv_LocalIp,EXCEPTION_DB_ERROR, CODEWHERE,"");
exit(-1);
}
}
return 0 ;
}
void *ProvTaskSend(void * prov)
{
int provid = *(int *)prov;
C_Node *tmpNode;
while(1)
{
……
省略程序比较多
//下发空转
sleep(2);
}
}
你觉着会有什么问题吗?我刚开始也没有想到会有什么问题,我将子线程中while循环设置空转,程序能正常运行,所以我一直认为是while循环体内程序有问题,但怎么都查不出来!
我gdb运行的时候也是正常的,这让我很崩溃,没法调试!
我又回头来想段错误一定是指针访问的问题,一定是非法了。
仔细分析后得出:创建线程的时候如果线程还没有完成创建(while循环中的程序比较多),代码段就退出了,那么临时变量都释放了,这么一来就段错误了。
修改程序:
int TaskSendControl()
{
static pthread_t prov_thread[CLIENT_NUM];
static int prov[CLIENT_NUM];
for(int i=0; i< CLIENT_NUM; i++)
{
prov[i] = i;
if( pthread_create(&prov_thread[i], NULL, ProvTaskSend, (void*)&prov[i] ) != 0 )
{
cout << "TaskSendControl" << endl;
gv_alert.InsertAlert(MAIN,1,gv_LocalName,gv_LocalIp,EXCEPTION_DB_ERROR, CODEWHERE,"");
exit(-1);
}
}
return 0 ;
}
果然程序正常运行!