【问题标题】:Delay the communication between two threads延迟两个线程之间的通信
【发布时间】:2012-05-21 17:08:10
【问题描述】:

我有两个线程(我在 GNU/Linux 上使用 pthreads)。现在他们正在使用全局变量共享信息(我知道,这不太好)。在每个周期结束时,他们必须将 5 个变量 (doubles) 的值发送到另一个线程。 我想在他们的沟通渠道中引入一个固定的时间延迟,

线程1(1kHz) 10ms 线程2(1kHz)

我在想,在每个循环中,我都可以创建一个读取值的线程,休眠 10 毫秒,然后将其转发到另一个线程,然后死掉。 这将使系统每个周期创建 2 个线程,一个用于通信通道的每个方向(每毫秒 2 个线程)。

还有其他智能方法可以模拟通信延迟吗?

更新:我不想同步线程的通信,而是在它们之间添加延迟。 如果 thread1 在 1s 时间写了一些东西,另一个线程应该只能在 1s + 10ms 时间读取它。

【问题讨论】:

  • 为什么每次都需要新建线程?
  • 您希望这种延迟作为同步的一种方式吗?如果是这样,那么这是一个可怕的想法。如果不是,那为什么会延迟?
  • @DavidHeffernan:我需要添加延迟以重现网络中的通信延迟。
  • @HonkyTonk:我不知道,这是我的第一个猜测。我是来寻求更好的解决方案的。
  • 您可以使用同步在写入器线程中设置基于时间的变量,并且仅在所需时间已过时才检查读取器中的其他变量(与基于时间的变量的值相比)

标签: c linux multithreading pthreads communication


【解决方案1】:

这听起来不像是性能问题,所以让它变得简单。无需复杂的数据结构、额外的线程等。

为您的数据创建一个结构,为其添加一个时间戳字段。

创建一个数组来保存至少 10 个结构。去100是安全的。不会在这里使用很多内存,所以谁在乎。哎呀,你可以在它需要增长时对其进行 malloc。

每个线程都有一个这样的数组,以及数组中的项目计数。

当一个线程准备好发送数据时,做两件事:

  1. 检查数组中第一项的时间戳,如果是旧的 足够将该数据发送到另一个线程。发送后递减 计数和记忆将数组中的其余项目向下移动一个 缺口。
  2. 将当前/新数据添加到数组末尾 当前时间戳并增加计数。

重复其他线程。

【讨论】:

  • 数据发送部分仍然需要某种线程同步机制
  • 我同意,我希望这个问题更多地是关于让消息需要 10 毫秒才能到达另一个线程的方法。本地 FIFO 解决了这个问题。他仍然需要使用原子操作或互斥锁来同步数据。
【解决方案2】:

为什么不直接使用互斥锁来同步两个线程之间的通信呢?

当第一个线程需要写入数据时,它会获取互斥锁(因此其他线程在第一个更新数据时无法读取数据),更新datam,然后释放互斥锁。另一个线程在读取数据时执行类似的获取/释放方法。

【讨论】:

  • 似乎 OP 希望全局变量像 FIFO 一样工作,并且这种方法不能保证这种行为(例如,写入线程不能获取互斥锁,写入数据,释放互斥锁,然后在读取器线程到达之前再次获取互斥锁?)
【解决方案3】:

我无法从这个问题中完全看出作者和读者线程之间的通信是否需要可靠(例如:作者线程发送的所有消息都保证以正确的顺序被读者线程看到)。如果是这样,并且如果您使用单个全局结构作为共享数据,那么您实际上是在实现一个缓冲区大小为 1 的 FIFO。线程间通信很容易出错,因此我建议您查看一些东西就像 glib 的 asynchronous queues。如果您需要从头开始实现自己的代码,那么查看该代码可能是一个不错的起点。

【讨论】:

  • 通讯要可靠,我去看看链接!谢谢!
【解决方案4】:

为什么不在这里使用信号量?您可以让一个线程在信号量上等待,并让另一个线程在它完成关键部分时发出信号。

【讨论】:

  • 我不想让线程等待,只想让一条信息从一个线程到另一个线程。还是谢谢!
  • @claudio 如果你想在线程之间进行可靠的通信,就必须有某种机制让一个线程等待另一个线程。它可能最终不会在实践中等待,具体取决于时间,但需要有机制来确保正确的行为。否则如何防止,例如,当写线程只写一半的时候读线程读?
  • @nighthawk 你这里不需要两个信号量吗?这是经典的producer-consumer problem,缓冲区大小为 1,传统上用两个二进制信号量实现(一个计算满槽,一个计算空槽)
  • 你可能是对的 - 你需要一些方法来防止消费者线程处理部分写入的数据。