我有一些我想从数据库缓存的状态数据.多个线程中的任何一个都可以修改状态数据.修改数据后,它将被写入数据库.数据库写入将始终由底层数据库访问层按顺序完成,该数据库访问层将数据库操作排入不同进程,因此我不关心那些竞争条件.
仅修改几个线程的静态数据是一个问题吗?从理论上讲,修改可以实现为读取,修改,写入,但在实践中我无法想象这是如此.
我的数据处理类看起来像这样:
class StatusCache { public: static void SetActivityStarted(bool activityStarted) { m_activityStarted = activityStarted; WriteToDB(); } static void SetActivityComplete(bool activityComplete); { m_activityComplete = activityComplete; WriteToDB(); } static void SetProcessReady(bool processReady); { m_processReady = processReady; WriteToDB(); } static void SetProcessPending(bool processPending); { m_processPending = processPending; WriteToDB(); } private: static void WriteToDB(); // will write all the class data to the db (multiple requests will happen in series) static bool m_activityStarted; static bool m_activityComplete; static bool m_processReady; static bool m_processPending; };
我不想使用锁,因为应用程序的这一部分已经有几个锁,添加更多会增加死锁的可能性.
如果数据库更新中的两个线程之间存在一些重叠并不重要,例如
thread 1 thread 2 activity started in db SetActivityStarted(true) SetActivityStarted(false) m_activityStated = true m_activityStarted = false WriteToDB() false WriteToDB() false
因此db显示最近由m _... = x行设置的状态.还行吧.
这是一种合理的使用方法还是有更好的方法?
[编辑说我只关心最后的状态 - 顺序不重要]
不,这不安全.
生成的代码用于写入m_activityStarted,而其他代码可能是原子的,但这并不是garantueed.此外,在你的setter中你做两件事:设置一个布尔值并进行调用.这肯定不是原子的.
你最好使用某种锁来同步这里.
例如,一个线程可以调用第一个函数,并且在该线程进入"WriteDB()"之前,另一个线程可以调用另一个函数并进入WriteDB()而不首先去那里.然后,状态可能以错误的顺序写入DB.
如果您担心死锁,那么您应该修改整个并发策略.