在C语言中释放被阻塞流的缓冲区

4
在一个多线程应用程序中,我需要取消一些线程。其中一些使用flockfile机制,但显然不是pthread_cancel的有效取消点。我通过使用pthread_kill发送SIGUSR1信号来结束这些线程,在信号处理程序中强制它们执行pthread_exit,从而成功地终止了它们。在我的情况下清理分配的内存很简单(都在堆栈上),但我当然无法关闭文件流。有没有办法释放缓冲区或删除锁定?在我的系统中,每个未关闭的缓冲区占用16KB的内存,这会很快积累。

这只是一个解决方法,但有ftrylockfile函数。 - Karoly Horvath
嗯,使用 lockf 可以进行“重新设计”,但是... - Mat
我尝试了ftrylockfile,但只有在线程尚未获取锁时才有用。有时它会在被锁定的通道中间捕捉到线程,这又是同样的问题。嗯,lockf似乎是在进程级别上实现的? - Ynv
你说的“进程级别”是什么意思?在Linux上,lockf是通过fcntl(F_SETLKW)实现的。它不是在用户空间中完成的,也不是进程私有锁。 - Mat
1个回答

2

与其强制杀死线程,您应该向它们发送“完成”消息,然后线程可以在退出前自行清理。

您已经使用SIGUSR1执行了消息传递部分,因此需要跟踪打开的句柄,以便您可以从信号处理程序中解锁/释放任何正在使用的句柄。


我有文件句柄,但除了刚刚被杀死的线程之外,您无法从另一个线程解锁它们。信号处理程序中没有任何信息可以让被信号通知的线程对此采取行动。 - Ynv
除非被信号的线程被阻塞,否则你可以发送一条消息给它(跟踪哪些线程“拥有”你锁定的资源)以解锁该资源。如果线程被阻塞,你应该更改所使用的阻塞机制以允许中断(例如,仅阻塞特定时间,然后检查是否需要退出,如果不需要则再次阻塞)。 - Attila
是的,它被阻塞了,极有可能。阻塞调用在流上进行 getc_unlocked 调用。是否有非阻塞版本的 getc,我找不到了? - Ynv
手册中可以得知,如果您使用非阻塞套接字,则可以在此时没有可读内容时重新尝试(返回值:EWOULDBLOCK):睡眠,检查退出条件并再次尝试读取。 - Attila
1
你可以使用fcntl以非阻塞模式打开文件。 - Attila

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接