线程同步以确保线程不重叠

时间:2015-07-30 21:03:11

标签: c++ multithreading boost

我有两个线程,其中一个独立运行,周期为1秒。第二个线程发送一些请求,与第一个线程并行,并且在第二个线程的一个特定请求期间,第一个线程和第二个线程的请求之间的差异应该至少为50毫秒。如何确保第一个线程的请求与第二个线程的特定请求不重叠?

我想在第二个线程中获取第一个线程的时间戳,并让第一个线程在开始再次发送请求之前休眠50ms。解决方案可行吗?在C ++中有可能吗?如果没有,如果你建议一个解决方案会有所帮助。我是线程新手,所以请不要介意它是否是一个愚蠢的问题。

编辑: 有人可以使用Boost Library向我提供一个如何执行此操作的示例。两个线程,第一个线程和第二个线程也用两个不同的dll编写。

2 个答案:

答案 0 :(得分:0)

[编辑: 正如Mateusz Grzejek在评论中所说,std::condition_variable实际上更适合这种用法(我仍然不确定为什么这个解决方案被视为无效,但即使它不是,<\ n / s>使用condition_variable,而不是比较和交换) ]

[编辑:以下(和我原来的)解决方案实际上并不起作用,因为当您检索当前时间时,您对其合法性(尤其是高精度)没有任何保证,因此不能保证你在100ms之后实际上不能获得相同的时间戳,或者相反甚至可以在100ms内跳跃500ms。
一般来说,正如Mateusz Grzejek所说,你不应该依赖于直接检索同步的时间戳,而是使用专用函数,它会在给定的时间后锁定/解锁(幸运的是std::condition_variable似乎允许这样做,就像Mateusz一样) Grzejek说) ]

这是可行的,你可以有一个原子时间戳(以毫秒为单位)变量,这将是下一次线程能够发送下一个请求,然后当一个线程想要发送请求时,它遵循以下步骤:

  • 首先在本地变量中加载该时间戳的值

  • 检查该值是否大于当前时间戳(如果是,请为差异休眠,然后从头开始)

  • compare-and-swaphttp://en.cppreference.com/w/cpp/atomic/atomic_compare_exchange)时间戳和您的本地变量(如果它们相等,则将其设置为当前时间,以毫秒为单位+50)

  • 如果比较和交换成功,发送请求,否则,睡眠50ms并从头开始

编辑:&#34; atomic&#34;操作意味着没有其他线程可以中断该操作,你不能将其分开,因此&#34; atomic&#34; (这些步骤中的每一个都可以被其他线程中断,然后再追逐,除了原子比较和交换,这很重要)

答案 1 :(得分:0)

根据您正在运行的环境,应该知道滴答率。对于Window XP或更高版本,默认滴答率为64 hz或15.625 ms,您可以使用timeBeginPeriod()更改此值,将速率设置为1000hz或1ms,但在Windows XP的情况下,它最终为1024hz,每128个滴答(在第43,第86,第128个刻度)有3个双延迟(2 / 1024hz),最终得到125毫秒边界。您可以在从第一个线程发送请求之后,在从第二个线程发送请求之前读取时间戳,但是第二个线程的潜在问题会延迟近1秒并最终在50ms内发送它的特殊请求第一个线程下一个请求。

您可以通过同步的fifo消息传递系统(例如,每个线程具有单独的头指针,互斥锁和信号量的单个链表)向第三个线程发送所有请求,该第三个线程检索请求并发送实际请求。消息将包括线程ID和特殊请求标识符。在发送请求之前,第三个线程将根据需要执行50 ms的延迟。