你的设置非常DBish.你有一个由Clients类表示的表,以及CLIENTOBJ的几个实例,每个实例都像表的一行,id作为主键.但据我所知,每个客户端实际上都是一个数据队列.
数据库使用的模型可以粗略地描述为将对数据的任何访问权委托给数据库中的专用活动(线程或进程),并使用SQL向其发送命令.使用事务和SQL子句处理同步问题(如果查找的id不存在,更新可能不会影响任何行,但该命令不会失败,它将只返回0行更新).在您的情况下,类似的模型可能会很有趣:只有一个全局互斥体来表示事务,每个线程锁定整个数据结构,操作它并解锁.但是,这可能效率不高.
异步等价物是让每个命令返回一个std :: future而不是实际结果.从那时起,线程只需要等待将来,并在它完成时对其进行操作(或者在例外情况下被破坏).
在Clients实例中,任何方法调用都将转换为future和promise. promise被推送到promise队列,并且调用线程要么从方法调用中获取未来,要么立即等待它.
从数据库进程的角度来看,这是一个顺序工作:你有一个promise队列,所有其他线程都将所有其他线程推送到必须去的客户端id捆绑的数据.然后,DB线程按顺序满足结果承诺:
>创建一个新客户端
>删除客户端
>如果它是存储,则数据库线程检查是否有任何读取待处理,并且满足它,或者只是将该数据放入客户端队列中
>如果它是读取数据,则将其从客户端队列中拉出并将其提供给线程,或将其推送到客户端的挂起读取队列,以便稍后在数据可用时满足.
通过上述解决方案,可以分离所有依赖关系并简化任务.
您也可以为每个CLIENTOBJ专用一个线程.然后,DB线程成为一个分类线程,它只是将promises分发给每个客户端.每个客户端拥有给定id的挂起读取和数据队列,因此在处理promises时不会涉及锁定.
必须使用互斥锁保护每个队列,这意味着主承诺队列为1个互斥,每个客户端承诺队列为1个互斥,以及使用Clients方法的线程数量多于条件变量.
更新:
我的回答最初提出以下建议:
In other words, you could replace the future/promise mechanism by a simple condition variable associated to each non DB threads (future and promise are probably implemented using a cond. variable, but here you would save the creation and destruction overhead).
但它对CLIENTS对象的使用方式做了一些隐含的假设.最安全的道路确实是std :: future.