如何在写线程和读线程之间同步数据库访问?

时间:2010-04-02 23:23:32

标签: c++ mysql multithreading mutex

我的程序有两个主题:

  1. 处理用户输入并将数据库写入队列的主执行线程
  2. 每秒唤醒并刷新对数据库的写入的实用程序线程
  3. 在主线程中,我偶尔需要对数据库进行读取。当发生这种情况时,性能并不重要,但正确性是。 (在一个完美的世界里,我会从缓存中读取,而不是到数据库的往返 - 但为了讨论,我们把它放在一边。)

    如何确保主线程看到正确/静止的数据库?

    标准互斥锁不起作用,因为我冒着让主线程在数据刷新到数据库之前获取互斥锁的风险。这将是一个很大的竞争条件。

    我真正想要的是某种互斥体,只有在互斥锁被抓取并释放一次之后才能执行主线程。这样的事情存在吗?解决这个问题的最佳方法是什么?

    更新:在做了一些额外的研究后,我可能会使用Boost's Conditional Variable来解决这个问题。要么那么,要么只是咬紧牙关并缓存我的写作。感谢您的反馈!

3 个答案:

答案 0 :(得分:3)

您提出的解决方案肯定仍然会导致竞争条件,因为“写入”可能随时出现,即使是排队的新事件的中途。

您可能尝试的解决方案是原子数据库状态值:您进行处理,然后与原子状态值进行比较,以确保您从处于与开始读取时相同状态的数据库中读取数据。如果它不同,你重新开始。这可能会受到饥饿的影响,但这是一个单独的问题。

每次更改数据库时,都必须比较并交换使用的原子状态值,表示更改。

答案 1 :(得分:3)

可能有几种解决方案:

  • 让每个线程打开自己的d / b连接并专门使用
  • 使用单个连接,但每个线程都拥有互斥锁以访问它。

我认为第二种选择没有问题。当没有什么可以冲洗时,冲洗的危害是什么?

答案 2 :(得分:1)

如果你没有多个主执行线程(即,唯一一个将写入工作线程的线程与将从数据库中读取的线程相同),那么你可能只需要一个简单的线程“待处理写入”变量/函数,您可以在发送读取之前检查,并自动锁定或等待信号,直到写入被刷新。听起来你不需要对写入执行任何锁定或同步,如果它们可以简单地排队等待工作线程处理。

基本上,只要保证在检查“挂起写入”状态和实际执行读取之间,就没有写入,那么你就不需要做任何太花哨的事情。