我有两个名为Writer和Reader的进程在同一台机器上运行。 Writer是一个单一的线程,将数据写入共享内存。 Reader有8个线程,它们打算同时从共享内存中读取数据。我需要一种符合以下标准的锁定机制:
1)一次允许Writer或Reader访问共享内存。
2)如果Reader有权从共享内存中读取数据,那么它自己的所有线程都可以读取数据。
3)作家必须等到读者完全"释放锁(因为它有多个线程)。
我已经阅读了很多关于可共享互斥的内容,这似乎是解决方案。在这里,我将详细介绍我的系统:
1)系统应该在Windows和Windows上运行Linux操作系统。
2)我将共享内存分为两个区域:lock&数据。数据区域进一步分为100个块。我打算创建100个"锁定对象" (可共享的互斥锁)并将它们放在锁定区域上。这些锁定对象用于同步100个数据块,1个锁定对象用于1个数据块。
3)Writer,读者首先确定它想要访问哪个块然后尝试获取适当的锁。一旦获得锁定,它就会在数据块上执行。
我现在关注的是:
有没有"内置"将锁定对象放在Windows和Linux(Centos)上的共享内存上的方法然后我可以使用对象锁定/解锁而不使用boost库。
答案 0 :(得分:1)
[编辑2016年2月25日,格林尼治标准时间09:30]
我可以提出一些建议。这实际上取决于要求。
如果看起来升级可升级的互斥锁符合要求,那么无论如何都要使用它。从5分钟阅读似乎你可以在shm中使用它们。我没有经验,因为我没有使用提升。 Boost可以在Windows和Linux上使用,因此我不明白为什么不使用它。您可以随时获取您喜欢的特定代码,并将其带入您的项目中,而不会拖累整个庞然大物 无论如何,测试它是否相当容易,看它是否足够好?
我不明白将锁放入shm的要求。如果它没有实际要求,并且您想要使用OS本机对象,则可以为每个OS使用不同的机制。比如说,在Linux上命名为mutex(不是shm),在Linux上命名为shm的pthread_rwlock。
我知道我更喜欢使用什么:seqlock
我在低延迟域工作,所以我选择了什么让我获得尽可能低的延迟。我在cpu周期中测量它
从你提到你想要锁定每个对象,而不是一个大锁,我认为性能很重要
但是,这里有一些重要的问题:
Spinlocks和seqlocks提供最大吞吐量和最小延迟。在内核支持的同步中,延迟的很大一部分用于在用户和内核空间之间切换。在大多数应用中,这不是问题,因为同步仅在一小部分时间内发生,并且几微秒的额外延迟可忽略不计。即使在游戏中,100帧每帧也会让你每帧10毫秒,这在互斥锁定/解锁方面是永恒的。
加法[2016年2月26日,格林尼治标准时间10:00]
如何添加自己的主人死亡检测:
Windows名为mutex和pthread robust mutex内置了此功能。使用其他锁类型时,自己添加它很容易,并且在使用基于用户空间的锁时可能是必不可少的。
首先,我必须说,在许多情况下,仅仅重新启动所有内容而不是检测所有者的死亡更合适。它肯定更简单,因为您还必须从不是原始所有者的进程中释放锁。
无论如何,在Windows上检测进程死亡的本地方法很容易 - 进程是可等待的对象,因此您可以等待它们。您可以等待零时间立即检查
在Linux上,只有父母应该知道它的孩子的死亡,所以不那么琐碎。父母可以获得SIGCHILD
,或使用waitpid()
。
我最喜欢检测过程死亡的方法是不同的。我在两个进程之间连接一个非阻塞的TCP套接字,并信任操作系统在进程死亡时将其终止
当您尝试从套接字(在任何一侧)读取数据时,如果对等体已经死亡,则您将读取0个字节。如果它仍然存在,您将获得EWOULDBLOCK
显然,这也可以在盒子之间工作,所以很方便一劳永逸地完成它。
你的工作循环必须改变以交错同伴死亡检查及其正常工作。
答案 1 :(得分:-2)
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/sync/interprocess_condition.hpp>**
//Mutex to protect access to the queue
boost::interprocess::interprocess_mutex mutex;
//Condition to wait when the queue is empty
boost::interprocess::interprocess_condition cond_empty;
//Condition to wait when the queue is full
boost::interprocess::interprocess_condition cond_full;