我有一个多线程应用程序,在Linux(Fedora 27)上运行的c ++中。线程之一继续使用低级IO(打开,读取等)从本地磁盘上的文件读取数据,并将该数据提供给在其他线程之间循环的缓冲区。
现在,我突然遇到一个奇怪的问题,在没有明显原因的情况下,read()会在文件中的任意偏移处无缘无故地开始无限阻塞。我添加了一个监视线程,该线程可以检测到此块(通过在输入read()之前设置时间戳)并尝试在程序发生时关闭程序。
现在很奇怪的是,在主线程的末尾,它等待pthread_join
,并在该读取线程上-它返回0(成功)。
我再次尝试,但是用read()
替换了对while(1);
的调用,现在pthread_join
未能按预期完成。
然后我检查了gdb中的程序,令我惊讶的是,当我到达pthread_join
时,读取线程消失了!
当监视线程检测到阻塞info thread
时,看着read()
,该线程仍在那儿,但是在某个时候它消失了,我无法抓住它!
我正在尝试捕获该线程退出,并且正在寻找有关如何执行此操作的想法。我正在使用pthread_cleanup_push/pop
,但是我的函数未由读取线程调用(所有其他线程都在调用)。
有什么想法吗?我无能为力!
编辑----------------------------------------
它似乎与从完全不相关的线程中调用syslog
有关。
答案 0 :(得分:1)
read
是取消点,因此,如果您的应用程序调用{{1}}在某个点终止线程,则该线程将不复存在(在执行清除操作之后)。加入取消的线程会成功,并会为pthread_cancel
值生成一个特殊值PTHREAD_CANCELED
,该值可选地由void *
填充。
如果用无限循环替换pthread_join
,则没有取消点,取消请求没有作用,read
也将无限期等待。