gpt4 book ai didi

unix - 共享内存中的条件变量 - 此代码符合 POSIX 标准吗?

转载 作者:行者123 更新时间:2023-12-04 18:16:20 29 4
gpt4 key购买 nike

POSIX 标准是否允许 命名为 共享内存块包含互斥锁和条件变量?
我们一直在尝试使用互斥锁和条件变量来同步 LynuxWorks LynxOS-SE system 上的两个进程对命名共享内存的访问。 (符合 POSIX 标准)。
一个共享内存块称为 "/sync"并包含互斥量和条件变量,另一个是"/data"并包含我们正在同步访问的实际数据。
我们看到来自 pthread_cond_signal() 的失败如果两个进程都不执行 mmap()来电完全相同的订单 , 或者如果一个进程在映射 "/sync" 之前映射到另一 block 共享内存中内存。
这个示例代码尽可能短:

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/file.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include <iostream>
#include <string>
using namespace std;

static const string shm_name_sync("/sync");
static const string shm_name_data("/data");

struct shared_memory_sync
{
pthread_mutex_t mutex;
pthread_cond_t condition;
};

struct shared_memory_data
{
int a;
int b;
};


//Create 2 shared memory objects
// - sync contains 2 shared synchronisation objects (mutex and condition)
// - data not important
void create()
{
// Create and map 'sync' shared memory
int fd_sync = shm_open(shm_name_sync.c_str(), O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);
ftruncate(fd_sync, sizeof(shared_memory_sync));
void* addr_sync = mmap(0, sizeof(shared_memory_sync), PROT_READ|PROT_WRITE, MAP_SHARED, fd_sync, 0);
shared_memory_sync* p_sync = static_cast<shared_memory_sync*> (addr_sync);

// init the cond and mutex
pthread_condattr_t cond_attr;
pthread_condattr_init(&cond_attr);
pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED);
pthread_cond_init(&(p_sync->condition), &cond_attr);
pthread_condattr_destroy(&cond_attr);

pthread_mutexattr_t m_attr;
pthread_mutexattr_init(&m_attr);
pthread_mutexattr_setpshared(&m_attr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(&(p_sync->mutex), &m_attr);
pthread_mutexattr_destroy(&m_attr);

// Create the 'data' shared memory
int fd_data = shm_open(shm_name_data.c_str(), O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);
ftruncate(fd_data, sizeof(shared_memory_data));

void* addr_data = mmap(0, sizeof(shared_memory_data), PROT_READ|PROT_WRITE, MAP_SHARED, fd_data, 0);
shared_memory_data* p_data = static_cast<shared_memory_data*> (addr_data);

// Run the second process while it sleeps here.
sleep(10);

int res = pthread_cond_signal(&(p_sync->condition));
assert(res==0); // <--- !!!THIS ASSERT WILL FAIL ON LYNXOS!!!

munmap(addr_sync, sizeof(shared_memory_sync));
shm_unlink(shm_name_sync.c_str());
munmap(addr_data, sizeof(shared_memory_data));
shm_unlink(shm_name_data.c_str());
}

//Open the same 2 shared memory objects but in reverse order
// - data
// - sync
void open()
{
sleep(2);
int fd_data = shm_open(shm_name_data.c_str(), O_RDWR, S_IRUSR|S_IWUSR);
void* addr_data = mmap(0, sizeof(shared_memory_data), PROT_READ|PROT_WRITE, MAP_SHARED, fd_data, 0);
shared_memory_data* p_data = static_cast<shared_memory_data*> (addr_data);

int fd_sync = shm_open(shm_name_sync.c_str(), O_RDWR, S_IRUSR|S_IWUSR);
void* addr_sync = mmap(0, sizeof(shared_memory_sync), PROT_READ|PROT_WRITE, MAP_SHARED, fd_sync, 0);
shared_memory_sync* p_sync = static_cast<shared_memory_sync*> (addr_sync);

// Wait on the condvar
pthread_mutex_lock(&(p_sync->mutex));
pthread_cond_wait(&(p_sync->condition), &(p_sync->mutex));
pthread_mutex_unlock(&(p_sync->mutex));

munmap(addr_sync, sizeof(shared_memory_sync));
munmap(addr_data, sizeof(shared_memory_data));
}

int main(int argc, char** argv)
{
if(argc>1)
{
open();
}
else
{
create();
}

return (0);
}
不带 args 运行这个程序,然后运行另一个带 args 的副本,第一个将在断言检查 pthread_cond_signal() 时失败。 .
但是改变 open()的顺序函数到 mmap() "/sync " "/data" 之前的内存,它会正常工作。
对我来说,这似乎是 LynxOS 中的一个主要错误,但 LynuxWorks 声称以这种方式在命名共享内存中使用互斥锁和条件变量不受 POSIX 标准的覆盖,因此他们不感兴趣。
谁能确定这段代码是否确实违反了 POSIX?
或者是否有人有任何令人信服的文档证明它符合 POSIX?
编辑 : 我们知道 PTHREAD_PROCESS_SHARED是 POSIX 并受 LynxOS 支持。争论的焦点是互斥体和信号量是否可以在命名共享内存中使用(正如我们所做的那样),或者 POSIX 是否只允许在一个进程创建并映射共享内存然后 fork 第二个进程时使用它们。

最佳答案

我可以很容易地看到 PTHREAD_PROCESS_SHARED 在操作系统级别上实现起来是多么棘手(例如,MacOS 没有,除了 rwlocks 似乎)。但是仅仅从阅读标准来看,您似乎有一个案例。

为完整起见,您可能想要断言 sysconf(_SC_THREAD_PROCESS_SHARED)以及 *_setpshared() 函数调用的返回值——也许还有另一个“惊喜”在等着你(但我可以从评论中看到你已经检查过 SHARED 确实受支持)。

@JesperE:您可能想引用 API docs at the OpenGroup而不是 HP 文档。

关于unix - 共享内存中的条件变量 - 此代码符合 POSIX 标准吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2782883/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com