【发布时间】:2016-02-09 21:06:55
【问题描述】:
我在共享内存中有一个队列。它可以在 Linux(内核 4.3.4)上运行,但不能在 Mac OS X 上运行。Mac OS X 处理共享内存的方式与 linux 的处理方式之间是否存在差异,这可以解释这一点吗?
我通过以下方式获得共享内存:
int sh_fd = shm_open(shmName, O_RDWR | O_CREAT,
S_IROTH | S_IWOTH // others hav read/write permission
| S_IRUSR | S_IWUSR // I have read/write permission
);
// bring the shared memory to the desired size
ftruncate(sh_fd, getpagesize());
队列也很简单。这是基本结构:
typedef struct {
// this is to check whether the queue is initialized.
// on linux, this will be 0 initially
bool isInitialized;
// mutex to protect concurrent access
pthread_mutex_t access;
// condition for the reader, readers should wait here
pthread_cond_t reader;
// condition for the writer, writers should wait here
pthread_cond_t writer;
// whether the queue can still be used.
bool isOpen;
// maximum capacity of the queue.
int32_t capacity;
// current position of the reader and number of items.
int32_t readPos, items;
// entries in the queue. The array actually is longer, which means it uses the space behind the struct.
entry entries[1];
} shared_queue;
基本上每个想要访问的人都会获得互斥体,readPos 表示应该读取下一个值的位置(之后增加 readPos),(readPos+items) % capacity 是新项目的位置。唯一有点花哨的技巧是 isInitialized 字节。如果之前长度为 0,ftruncate 会用零填充共享内存,因此我依赖 isInitialized 在新的共享内存页面上为零,并在初始化结构后立即在此处写入 1。
正如我所说,它适用于 Linux,所以我不认为这是一个简单的实现错误。 Mac 上的 shm_open 与我可能不知道的 Linux 上的 shm_open 之间有什么细微的区别吗?我看到的错误看起来像是读者试图从一个空队列中读取,所以,也许 pthread 互斥/条件不适用于 Mac 中的共享内存?
【问题讨论】:
-
我不明白
isInitialised和ftruncate之间的联系。你能详细说明一下吗? -
@terencehill - 我很确定他对那个标志所做的任何“花哨的技巧”都不足以(在一般情况下)阻止两个进程尝试初始化同一个队列并保证没有进程曾经尝试使用未初始化的队列。请参阅下面我编辑的答案...
标签: c linux macos shared-memory