C++ 等待直到系统时间更改的条件变量解决方法
C++ 等待直到系统时间更改的条件变量解决方法,c++,linux,gcc,condition-variable,C++,Linux,Gcc,Condition Variable,我有一个定时器类,它使用std::condition\u变量wait\u直到(我还尝试了wait\u for)。我正在使用std::chrono::staid_clock time等待未来的特定时间
这意味着是单调的,但长期存在的问题是,这实际上使用了系统时钟,并且在系统时间改变时无法正常工作
它已在libc中修复,如下所示:
问题是,到2019年,这仍然是一个非常新的版本,仅在gcc版本10中可用。我有一些交叉编译器,它们只升级到gcc版本8
我想知道是否有办法将此修复程序添加到我的gcc版本
我有一个定时器类,它使用std::condition\u变量
wait\u直到
(我还尝试了wait\u for
)。我正在使用std::chrono::staid_clock time
等待未来的特定时间
这意味着是单调的,但长期存在的问题是,这实际上使用了系统时钟,并且在系统时间改变时无法正常工作
它已在libc中修复,如下所示:
问题是,到2019年,这仍然是一个非常新的版本,仅在gcc版本10中可用。我有一些交叉编译器,它们只升级到gcc版本8
我想知道是否有办法将此修复程序添加到我的gcc版本中(我有很多跨编译器)?-但是,如果每次更新交叉编译器时都必须重新构建交叉编译器,那么这可能很难维护
因此,更好的问题可能是,在我将所有工具升级到gcc v10之前,这个问题的解决方案是什么如何使计时器抵抗系统时间变化
更新注释
- Rustyx提到需要的glibc版本是2.3.0+(更多信息请参考-使用
ldd--version
检查)
- glibc变更日志,显示Daniel Langr提供的修复程序的相关条目:
- 所需的glibc补丁(由rustyx提供):
创建一个数据结构,其中包含一个条件变量列表,每个条件变量的使用计数受互斥锁保护
当线程即将阻塞条件变量时,首先获取互斥体并将条件变量添加到列表中(如果条件变量已经在列表中,则增加其使用计数)
阻塞条件变量后,让线程再次获取保护列表的互斥锁,并减少阻塞条件变量的使用计数。如果条件变量的使用计数降至零,请将其从列表中删除
有一个专用线程来监视系统时钟。如果检测到时钟跳变,则获取保护条件变量列表的互斥,并广播每个条件变量
就这样。这就解决了问题
如有必要,还可以向表中的每个条目添加布尔值,并在添加条目时将其设置为false。如果时钟观察线程已经广播了条件变量,让它将bool设置为true,这样被唤醒的线程将知道它们被唤醒的原因
如果愿意,可以在创建条件变量时将其添加到列表中,在销毁条件变量时将其从列表中删除。这将导致广播条件变量,如果时钟跳变,没有线程被阻塞,但这是无害的
以下是一些实施建议:
使用专用线程来观察时钟。一个容易看的东西是墙壁时间和系统正常运行时间时钟之间的偏移量
一件简单的事情是记录观察到的时间跳跃的数量,并在每次感觉到时间跳跃时增加它。等待条件时,可以使用以下逻辑:
注意时间跳跃的数量
按条件阻塞
当你醒来时,重新检查情况
如果不满足条件,请检查时间跳数
如果1和4的计数不匹配,则将其作为时间跳转唤醒处理
您可以将这一切打包,这样调用代码就不会有任何问题。它只是成为您的版本的另一个可能返回值
创建一个数据结构,其中包含一个条件变量列表,每个条件变量的使用计数受互斥锁保护
当线程即将阻塞条件变量时,首先获取互斥体并将条件变量添加到列表中(如果条件变量已经在列表中,则增加其使用计数)
阻塞条件变量后,让线程再次获取保护列表的互斥锁,并减少阻塞条件变量的使用计数。如果条件变量的使用计数降至零,请将其从列表中删除
有一个专用线程来监视系统时钟。如果检测到时钟跳变,则获取保护条件变量列表的互斥,并广播每个条件变量
就这样。这就解决了问题
如有必要,还可以向表中的每个条目添加布尔值,并在添加条目时将其设置为false。如果时钟观察线程已经广播了条件变量,让它将bool设置为true,这样被唤醒的线程将知道它们被唤醒的原因
如果愿意,可以在创建条件变量时将其添加到列表中,在销毁条件变量时将其从列表中删除。这将导致广播条件变量,如果时钟跳变,没有线程被阻塞,但这是无害的
以下是一些实施建议:
使用专用线程来观察时钟。一个容易看的东西是墙壁时间和系统正常运行时间时钟之间的偏移量
一件简单的事情是记录观察到的时间跳跃的数量,并在每次感觉到时间跳跃时增加它。等待条件时,可以使用以下逻辑:
注意时间跳跃的数量
按条件阻塞
当你醒来时,重新检查情况
如果不满足条件,请检查时间跳数
如果1和4的计数不匹配,则将其作为时间跳转唤醒处理
您可以将这一切打包,这样调用代码就不会有任何问题。它只是您的版本的另一个可能返回值。我相信这是libstdc++的问题,而不是编译器本身的问题。你不能独立于GCC升级你的“系统”libstdc++版本吗?这是一个。您需要glibc2.3.0+(pt