我为这个有些含糊不清的标题道歉,但我真的想不出更好的写作方式。
我正在为一个应该能够处理后台处理的类设计一个shell。但是,因为在启用后台处理时shell不等待子进程,所以我认为最好创建第二个线程,其唯一目的是在子进程完成时清理它。现在这个工作正常,直到子进程结束。当子进程结束时,我输入的下一个输入给我一个分段错误。使用gdb,我发现故障来自我的getline函数。
我测试了它,std :: cin似乎不是问题。而且,当没有背景时,整个工作正常,没有任何问题。
为了测试背景,我编写了一个程序a.out打印,睡眠十秒钟,然后在退出之前再次打印。 输出:
/Users/opname/Shell Project>./a.out&
/Users/opname/Shell Project>Sleep time!
ls
opshell a.out pseudocode.c test.txt
opshell.cpp a.out.dSYM shell.h test2.txt
opshell.dSYM gcctest.c sleeper.c testdir
/Users/opname/Shell Project>Awake time!
ls
Segmentation fault: 11
这是我分叉进程并创建新线程的代码:
pid_t cpid = fork();
if (cpid > 0) {
int status;
if (conc) { // if backgrounding enabled
pthread_t waiter;
struct tcpara *pm = (struct tcpara*) malloc(sizeof(struct tcpara));
pm->cpid = cpid;
pm->status = &status;
pthread_create(&waiter, NULL, &thread_handler, (void*)pm);
pthread_detach(waiter);
}
else waitpid(cpid, &status, 0);
break;
} else if (cpid == 0) {
loc += cmd;
execv(loc.c_str(), argv);
_exit(0);
}
这是服务员线程调用的子程序:
void *thread_handler(void *pm) {
struct tcpara *ofpm = (struct tcpara*) pm;
waitpid(ofpm->cpid, ofpm->status, 0);
free(pm);
return NULL;
}
答案 0 :(得分:0)
尝试动态分配状态变量。当线程必须使用它时,它不再存在,因为它超出了范围。
我认为它与waiter
的情况相同。
您可以尝试将它们设为静态。