今天遇到一個問題,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 ;
}
果然程序正常運行!