gpt4 book ai didi

c++ - 在 C++ 中的线程内实现多个计时器的最安全方法

转载 作者:太空宇宙 更新时间:2023-11-04 12:57:58 36 4
gpt4 key购买 nike

正如标题所说,我正在寻找用 C++(不是 C++ 11)实现多个计时器的最佳方法。我的想法是使用单个 pthread (posix) 来处理计时器。我至少需要 4 个定时器,3 个周期定时器和 1 个单发定时器。最小分辨率应为 1 秒(对于最短计时器)和 15 小时(对于最长计时器)。所有计时器应同时运行。

这些是我想到的不同实现(我不知道它们是线程环境中最安全的还是最简单的):

1) 像这样使用 itimerspec、sigaction 和 sigevent 结构:

static int Tcreate( char *name, timer_t *timerID, int expireMS, int intervalMS )
{
struct sigevent te;
struct itimerspec its;
struct sigaction sa;
int sigNo = SIGRTMIN;

sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = app;
sigemptyset(&sa.sa_mask);
if (sigaction(sigNo, &sa, NULL) == -1)
{
perror("sigaction");
}

/* Set and enable alarm */
te.sigev_notify = SIGEV_SIGNAL;
te.sigev_signo = sigNo;
te.sigev_value.sival_ptr = timerID;
timer_create(CLOCK_REALTIME, &te, timerID);

its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = intervalMS * 1000000;
its.it_value.tv_sec = 0;
its.it_value.tv_nsec = expireMS * 1000000;
timer_settime(*timerID, 0, &its, NULL);

return 1;
}

2) 使用 clock() 并检查时差,如下所示:

std::clock_t start;
double duration;
start = std::clock();
duration = ( std::clock() - start ) / (double) CLOCKS_PER_SEC;

3) 像这样使用 chrono:

auto diff = tp - chrono::system_clock::time_point();
cout << "diff:" << chrono::duration_cast<chrono::minutes>(diff).count()
<< " minute(s)" << endl;
Days days = chrono::duration_cast<Days>(diff);
cout << "diff:" << days.count() << " day(s)" << endl;

请将这些视为想法,而不是实际工作代码。

你对此有何看法?

最佳答案

如果您的计时器线程负责计时器,并且最小分辨率为 1 秒,并且计时不需要那么精确(即如果 +/- 0.1 秒是好的够了),那么定时器线程的一个简单实现就是只休眠 1 秒,检查是否有任何需要触发的定时器,然后重复,如以下伪代码所示:

repeat:
sleep 1
t = t+1
for timer in timers where timer(t) = true:
fire(timer)

困难的部分将是填充存储计时器的结构 - 大概计时器将由其他线程设置,可能由多个尝试同时设置计时器的线程设置。建议使用一些标准数据结构(如线程安全队列)将消息传递给计时器线程,然后在每个周期中更新计时器本身的集合:

repeat:
sleep 1
t = t+1
while new_timer_spec = pop(timer_queue):
add_timer(new_timer_spec)
for timer in timers where timer(t) = true:
fire(timer)

另一件需要考虑的事情是 fire(timer) 的性质——在这里做什么实际上取决于使用计时器的线程的需要。也许只设置一个它们可以读取的变量就足够了,或者这可能会触发线程可以监听的信号。

关于c++ - 在 C++ 中的线程内实现多个计时器的最安全方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45655802/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com