【问题标题】:Can I implement a single threaded timer in C?我可以在 C 中实现单线程计时器吗?
【发布时间】:2018-06-25 07:20:06
【问题描述】:

我正在尝试在 C 中实现 通信协议。我需要实现一个计时器(这样如果一段时间后还没有收到 ACK,发送方会认为数据包已经丢失,然后再次发送)。

在一个看起来像 C 的伪代码中,我想要这样的东西:

if (!ack_received(seqn) && timer_expired(seqn)) {
    send_packet(seqn);
    start_timer(seqn);
}

注意:seqn 是正在发送的数据包的序列号。 每个数据包都需要一个个人计时器

timer_expiredstart_timer如何实现?有没有办法在不使用多个线程的情况下做到这一点?

【问题讨论】:

  • IO是非阻塞的吗?
  • 如果没有具体的系统,这个问题就太宽泛了。这必须以系统/操作系统特定的方式完成。
  • 这段代码在哪个平台或操作系统上运行?请编辑您的问题以改进它(至少,通过更精确地标记它,例如 Linuxwinapi 等...)
  • 如果是 Linux 则可以使用 timer_create(),查看此手册页以获取 timer_create()
  • my old answers 之一显示了一种可能的方法。如果并发活动超时的数量很高,那么绝对时间使用最小堆会更有效(对于只有十几个或两个插槽,不要打扰)。请注意,该示例安装了没有 SA_RESTART 标志的计时器信号处理程序,因此它的传递将中断任何阻塞 I/O 操作(如果进程中只有一个线程)。

标签: c linux timer


【解决方案1】:

我可以在 C 中实现单线程计时器吗?

可能不在纯可移植 C99(或单线程 C11,请参阅 n1570)中。

但在实践中,您通常会为一些 operating system 编写代码,然后您将获得一些方法来设置计时器。在 Linux 上,请先阅读 time(7)。您可能还想使用多路复用呼叫,例如poll(2)(您给它一个延迟)。并了解更多关于其他system calls 的信息,请阅读intro(2)syscalls(2) 和一些不错的Linux 编程书籍(也许是旧的ALP,可免费下载)。

顺便说一句,您似乎正在编写与网络相关的代码。您实际上需要一些 API(例如Berkeley sockets),因此您可能会使用类似于操作系统的东西。

许多event loops 是单线程的,但提供了某种计时器。

或者也许(如果您没有任何操作系统)您正在为一些小型嵌入式硬件平台编写一些独立的 C(例如Arduino-like)。然后你有一些方法来轮询网络输入和设置计时器。

【讨论】:

  • 在 Windows 中,您也可以将 SetTimer 与 WM_TIMER 一起用于特定窗口。根据我的经验不是很准确。另一种选择是先获取一些 HANDLE,然后再获取 WaitForSingleObject(some_handle, delay_ms);。无需实现 WindowProc 回调即可工作。
【解决方案2】:

取决于您系统的架构,它可以以或多或少优雅的方式完成。

在具有单线程的简单程序中,只需声明包含起始时间戳的表。因此该函数将只检查当前时间戳、已保存时间戳和超时值之间的差异。您当然需要实现另一个函数,该函数将为特定超时计数器初始化表元素。

【讨论】:

    猜你喜欢
    • 2013-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-09
    • 1970-01-01
    • 1970-01-01
    • 2012-10-12
    • 1970-01-01
    相关资源
    最近更新 更多