加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 共享列表,多个条件,一个或多个条件变量?

发布时间:2020-12-16 07:03:54 所属栏目:百科 来源:网络整理
导读:考虑一下你有一个清单: class CLIENTS{public: CLIENTS(); ~CLIENTS(); bool addClient(); bool removeClient(); bool getDataFromClientObj(unsigned int id); bool storeDataInClientObj(unsigned int id);private: // vector,that contains all the clie
考虑一下你有一个清单:

class CLIENTS
{
public:

    CLIENTS();
    ~CLIENTS();

    bool addClient();
    bool removeClient();
    bool getDataFromClientObj(unsigned int id);
    bool storeDataInClientObj(unsigned int id);
private:

    // vector,that contains all the clients
    boost::ptr_vector<CLIENTOBJ> clients;

    // mutex for the client-list
    boost::mutex mutex;
};

进一步考虑,getDataFromClientObj()获取共享锁(互斥锁,私有).
除此之外,您希望能够通过getDataFromClient()从客户端获取数据.

如果客户端队列中根本没有数据,则getDataFromClient()将等待该客户端的条件变量,直到它有新的数据要读取.

嗯,这是我的问题:
只要getDataFromClient();等待,(因为这是一个多读者/单一作者列表),我无法添加新客户端或删除客户端,因为getDataFromClient()持有互斥锁.

如果你有一个列表,你将如何准确地解决这个场景,在等待客户端时,应该是特定客户端的条件变量的线程安全等待,能够删除或添加列表中的任何客户端吗?

所以这里再次是事实:

> Threadsafe List(多个读者/单个作者)
>能够随时添加客户端/删除客户端
>能够特定地等待每个客户端的(特定)条件(一个客户端可能已经将新数据存储在他自己的队列中,而另一个客户端没有;然后getDataFromClient()将等待直到新数据被读取)

我认为的问题是,鉴于每个客户端都有一个条件(伪代码:if(clientsqueue.isEmpty() – > wait),必须有多个条件变量(我错了吗?)

更多的信息:
操作系统:Windows 7
语言:C
编译器VS2010

解决方法

你的设置非常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.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读