使用线程的分段错误
Posted
技术标签:
【中文标题】使用线程的分段错误【英文标题】:Segmentation Fault Using threads 【发布时间】:2013-04-11 08:16:16 【问题描述】:我正在尝试构建自己的库来使用和调度线程。
系统以您可以make maximum 100 threads
的方式工作,使它们“准备就绪”。然后有一个调度器,每个时间段,把活跃的线程,放到就绪链表中,并在就绪链表中取第一个等待的线程。
我的测试人员正在创建500000
线程,每个线程都会创建一个新线程并尝试自行终止。第二个线程(第一个线程创建)做同样的事情。第三个只是终止自己。
这是测试员:
void f3()
printf("f3 before terminate\n");
uthread_terminate(uthread_get_tid());
printf("f3 after terminate\n");
void f2()
printf("f2 before spawn\n");
uthread_spawn(f3);
printf("f2 after spawn\n");
uthread_terminate(uthread_get_tid());
printf("f2 after termination\n");
void f1()
printf("f1 before spawn\n");
uthread_spawn(f2);
printf("f1 after spawn\n");
uthread_terminate(uthread_get_tid());
printf("f1 after termination\n");
int main(int argc, char **argv)
printf("test8:\n--------------\n");
cout << "* Output should be:\n";
cout << "--------------\n";
cout << "***1***\n";
cout << "***2***\n";
cout << "Output is:\n";
uthread_init(100);
printf("***1***\n");
for (volatile int i=0; i< 50000;++i)
uthread_spawn(f1);
printf("***2***\n");
uthread_terminate(0);
return 0;
当我的程序进入我的调度程序时出现“分段错误”:
static void scheduler()
DBG(("Schedular "))
nQuantum++;
if (ready.size()!=0)
if (active != NULL)
if (active->getState() == Thread::RUNNING)
active->setState(Thread::READY);
ready.push_back(active);
int val = sigsetjmp(*active->getEnv(),1);
if (val !=0)
blockTimerSignal(UNBLOCK);
return;
// Set new Active
active = ready.front();
DBG(("Active thread Id: %d",active->getTid()))
ready.pop_front();
DBG(("Doing pop front on ready list"))
DBG(("Number of threads in ready list is - %d",(ready.size())))
active->setQuantums(active->getQuantums()+1);
active->setState(Thread::RUNNING);
setTimer();
blockTimerSignal(UNBLOCK);
DBG(("UNBLOCKED"))
siglongjmp(*active->getEnv(),1);
DBG(("After siglong jmp"))
else
active->setQuantums(active->getQuantums()+1);
DBG(("Number of threads in ready list is - %d",(ready.size())))
blockTimerSignal(UNBLOCK);
在做siglongjmp(*active->getEnv(),1);
时
它只发生在主线程(程序的第一个 id 为 0 的线程)。 它也会在程序运行一段时间后发生,这意味着在程序的中间,它可以为活动线程执行 siglongjmp,但是当它在一段时间后再次尝试时,它会给出错误。
如果有帮助,添加我的终止功能:
int uthread_terminate(int tid)
DBG(("Terminate - %d", tid))
if (tid == 0)
// delete all (threads) - don't think it's needed because using stl!
// TODO : check if needed - and then delete all lists !
//Added by Roni - Deleting all lists!
while(!sleeping.empty())
delete (sleeping.front());
sleeping.pop_front();
while(!suspended.empty())
delete (suspended.front());
suspended.pop_front();
while(!ready.empty())
delete (ready.front());
ready.pop_front();
exit(0);
pThread t = getThread(tid);
if (t == NULL)
errmsgLibrary(THREAD_NOT_FOUND);
return FAIL;
Thread::threadState state = t->getState();
DBG(("Terminate - %d in State %d", tid, state))
DBG(("Number of threads in ready list is - %d",(ready.size())))
blockTimerSignal(BLOCK);
switch (state)
case (Thread::RUNNING):
//DBG(("Running Case"))
//DBG(("Active thread id is: %d ",active->getTid()))
delete active;
active = NULL;
//DBG(("Finsihed running Case"))
scheduler();
break;
case (Thread::READY):
//DBG(("ready Case"))
ready.remove(t);
delete t;
//DBG(("Finsihed ready Case"))
break;
case (Thread::SLEEP):
sleeping.remove(t);
delete t;
break;
case (Thread::SUSPENDED):
suspended.remove(t);
delete t;
break;
default:
break;
//DBG(("Number of threads in ready list is - %d",(ready.size())))
blockTimerSignal(UNBLOCK);
return SUCCESS;
【问题讨论】:
active
必须是 NULL
所以导致 SIGSEGV
在那一刻。您应该在每次调用时检查uthread_spawn(f3);
是否成功,因为您可能遇到线程限制或内存不足而导致失败。
@ReckHou Hou Hou 实际上,当我检查时,我只看到 f1 在起作用。这是什么意思?你有什么建议?
【参考方案1】:
猜测一下,您在这里使用的是siglongjmp
,并且可能不会在调用之间更改堆栈。
考虑改用getcontext()
、swapcontext()
和makecontext()
。
【讨论】:
以上是关于使用线程的分段错误的主要内容,如果未能解决你的问题,请参考以下文章