【发布时间】:2012-05-03 17:33:28
【问题描述】:
我有一些系统级代码,它会每隔一段时间触发一次计时器,并且有一个信号处理程序在这些信号到达时对其进行管理。这工作正常,似乎完全合理。主程序旁边还有两个单独的线程运行,但它们不共享任何变量,而是使用 glib 的异步队列仅向一个方向传递消息。
相同的代码使用 glib 的 GHashTable 来存储键/值对。当信号代码被注释出系统时,哈希表似乎运行良好。然而,当它被启用时,会出现一个奇怪的竞争条件,其中对 g_hash_table_lookup 的调用实际上返回 NULL(这意味着没有用于查找它的键的条目),而实际上该条目确实存在(是的,我通过使用g_hash_table_foreach 打印整个键/值对列表来确保。为什么大多数时候会出现这种情况? GLib 的哈希表实现有问题吗?有时查找调用是成功的。
这是一个非常特殊的情况,如果它没有意义,我可以进一步澄清,但我希望我做错了什么,以便实际上可以解决这个问题。
更多信息:不在信号处理程序范围内但访问 g_hash_table 变量的代码段被信号阻塞调用包围,因此信号处理程序在进程最初访问它们时也不会访问这些变量。
【问题讨论】:
-
当您说“相同的代码...”时,您的意思是信号处理程序本身正在使用 GHashTable API?还是只是并行线程?
-
是的,信号处理程序使用 g_hash_table_remove()。
-
您可能不应该在信号处理程序中进行哈希表工作;检查
signal(7)以获取可以在信号处理程序中调用的安全函数列表,并为相当短的列表做好准备。 -
天哪,这永远不会可靠地工作。
-
@emish 你正处于一个充满伤害的世界,我的朋友。
标签: c thread-safety system signals glib