我有一个程序试图通过实现的池使用create和cancel。
创作如下:
while (created<threadsNum){
pthread_t newThread;
pthread_struct *st; //Open the thread that handle the deleting of the sessions timeout.
st = (pthread_struct*)malloc(sizeof(pthread_struct));
st->id = created;
st->t = &newThread;
pthread_mutex_lock( &mutex_threadsPool );
readingThreadsPool[created] = st;
pthread_mutex_unlock( &mutex_threadsPool );
if((threadRes1 = pthread_create( &newThread, NULL, pcapReadingThread, (void*)created)))
{
syslog(LOG_CRIT, "Creating Pcap-Reading Thread %d failed.",created);
printf( "Creating Pcap-Reading Thread %d failed.\n",created);
exit(1);
}
syslog(LOG_INFO, "Created Pcap-Reading Thread %d Successfully.",created);
created++;
}
稍后我尝试取消它们并重新启动它们:
pthread_t* t;
pthread_struct* tstr;
int i;
pthread_mutex_unlock( &mutex_threadsPool );
//first go on array and kill all threads
for(i = 0; i<threadsNum ; i++ ){
tstr = readingThreadsPool[i];
if (tstr!=NULL){
t = tstr->t;
//Reaches here :-)
if (pthread_cancel(*t)!=0){
perror("ERROR : Could not kill thread");
}
else{
printf("Killed Thread %d \n",i);
}
//doesnt reach here
}
}
我检查了第一部分中创建的线程的内存中的地址以及第二部分中即将被取消的线程的地址..它们匹配.. 我读到了如果调用killall()而无法工作的线程管理器。
但我没有......
有人有任何想法吗?
由于
答案 0 :(得分:1)
while (created<threadsNum){
pthread_t newThread;
pthread_struct *st;
/* ... */
st->t = &newThread;
/* ... */
}
你有st->t
指向局部变量newThread
。 newThread
仅在当前循环迭代期间的范围内。在此迭代之后,st->t
将包含无效的地址。
newThread
在堆栈上,因此在超出范围后,堆栈空间将用于其他变量。在连续迭代中,这可能是不同的pthread_t
,或者一旦循环结束,那么堆栈空间将用于完全不同类型的值。
要解决此问题,我可能会将pthread_struct.t
更改为pthread_t
而不是pthread_t *
,然后将pthread_create调用更改为:
pthread_create(&st->t, /*...*/)
另外,在调用st
之前,应该注意在线程池中添加pthread_create
。它可能应该在之后添加。就目前而言,有一个小窗口,其中st->t
在线程池上,但尚未初始化。