我有一个使用pthreads的项目;主线程和子线程以及它们之间的管道。这一切都很好,除了有时它不起作用。子线程运行命令解释器,并且基于ncurses的GUI通过管道向其传送(一些)输入。
我正常创建线程(线程是pthread_t文件范围变量,interp_start是函数)
if (pthread_create(&thread, NULL, interp_start, NULL)) { perror("couldn't create thread"); return; }
然后,如果解释器线程收到用户的“exit”命令,则调用interp_exit
fclose(output);
pthread_exit(NULL);
主线程有一个select(),它检查输出的FD,并调用从FD读取()的函数:
int num=read(interp_output[0], &ch, 1);
if (num==0) shell_done();
if (num==-1) perror("read");
通常可行的预期行为是关闭线程中的FILE *,这使得select()报告就绪,这使得read()发生,返回0,调用shell_done()。经过一些简单而无关的清理后,这样做了:
//fprintf(stderr, "joining thread\n");
pthread_join(thread, NULL);
//fprintf(stderr, "joined\n");
exit(EXIT_SUCCESS);
所有这些有时段错误。通常很好。如果我取消注释这两个printfs,如果它失败,我得不到(它在pthread_exit中的段错误)或者只是第一个(它在pthread_join中的段错误)。
我并没有在任何其他方面弄乱“线程”,而我只处理空指针。这是怎么回事?我会在其他地方寻找,除非我在这两行之一一直遇到问题 - 甚至在restore_sem_to_pool。我认为它必须是我杀死线程的方式,但我正在做最简单的事情。
提前致谢...
答案 0 :(得分:6)
尝试使用valgrind
(特别是“memcheck”部分)。它可以快速帮助您在运行时查明无效的内存访问,有时甚至包括运行不会崩溃的程序。
答案 1 :(得分:0)
我怀疑这是所有这些的组合,但问题消失了。它只发生在我在程序启动后过早输入“退出”时,但我现在没有时间对此进行正确调试,而且无论如何都要进行分配。 @John - 我实际上是为了这个目的而设立valgrind。 [编辑] 我早点跑了它并没有帮助我解决这个问题,但我确实发现了一些我没有释放的记忆 [/编辑] 其他人 - 我认为你是对的,这可能是某种内存腐败。 @caf - 我忘了检查其他线程......但我在两个线程中都看到了问题。 GDB指着我实际上是segfaulting的那个。 [编辑] 我检查了其他线程,它正在等待pt_join(如果segfault与pt_exit一起)或者在pt_exit之前的某个地方(如果segfault在pt_join中) [/编辑] 强>
投票给所有人,但我不认为在这里接受答案是公平的。