Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unix 共享内存中的条件变量-此代码与POSIX一致吗?_Unix_Ipc_Posix_Shared Memory_Lynxos - Fatal编程技术网

Unix 共享内存中的条件变量-此代码与POSIX一致吗?

Unix 共享内存中的条件变量-此代码与POSIX一致吗?,unix,ipc,posix,shared-memory,lynxos,Unix,Ipc,Posix,Shared Memory,Lynxos,POSIX标准是否允许名为的共享内存块包含互斥和条件变量 我们一直在尝试使用互斥体和条件变量,通过一个(POSIX一致性)上的两个进程同步对命名共享内存的访问 一个共享内存块称为“/sync”,包含互斥和条件变量,另一个是“/data”,包含我们正在同步访问的实际数据 如果两个进程在中执行mmap()调用的顺序不完全相同,或者如果一个进程在mmaps“/sync”内存之前在另一块共享内存中mmaps,我们就会看到pthread\u cond\u signal()的失败 此示例代码尽可能简短: #

POSIX标准是否允许名为的共享内存块包含互斥和条件变量

我们一直在尝试使用互斥体和条件变量,通过一个(POSIX一致性)上的两个进程同步对命名共享内存的访问

一个共享内存块称为
“/sync”
,包含互斥和条件变量,另一个是
“/data”
,包含我们正在同步访问的实际数据

如果两个进程在中执行
mmap()
调用的顺序不完全相同
,或者如果一个进程在mmaps
“/sync”
内存之前在另一块共享内存中mmaps,我们就会看到
pthread\u cond\u signal()
的失败

此示例代码尽可能简短:

#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);
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
静态常量字符串shm_name_sync(“/sync”);
静态常量字符串shm_name_data(“/data”);
结构共享内存同步
{
pthread_mutex_t mutex;
p线程条件;
};
结构共享内存数据
{
INTA;
int b;
};
//创建2个共享内存对象
//-同步包含2个共享同步对象(互斥和条件)
//-数据不重要
void create()
{
//创建并映射“同步”共享内存
int fd_sync=shm_open(shm_name_sync.c_str(),O_CREAT | O|u RDWR,S_IRUSR | S|u IWUSR);
ftruncate(fd_sync,sizeof(共享内存_sync));
void*addr\u sync=mmap(0,sizeof(共享内存同步),PROT\u READ | PROT\u WRITE,MAP\u shared,fd\u sync,0);
共享内存同步*p同步=静态同步(地址同步);
//初始化cond和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_mutextatr_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);
//创建“数据”共享内存
int fd_data=shm_open(shm_name_data.c_str(),O_CREAT | O|u RDWR,S_IRUSR | S|IWUSR);
ftruncate(fd_数据,sizeof(共享内存_数据));
void*addr_data=mmap(0,sizeof(共享内存数据),PROT_READ | PROT_WRITE,MAP_shared,fd_data,0);
共享内存数据*p数据=静态数据转换(添加数据);
//在第二个进程休眠时运行它。
睡眠(10);
int res=pthread_cond_信号(&(p_sync->condition));
断言(res==0);//互斥);
pthread_cond_wait(&(p_sync->condition),&(p_sync->mutex));
pthread_mutex_unlock(&(p_sync->mutex));
munmap(addr_sync,sizeof(共享内存同步));
munmap(addr_数据,sizeof(共享内存数据));
}
int main(int argc,字符**argv)
{
如果(argc>1)
{
open();
}
其他的
{
创建();
}
返回(0);
}
不使用args运行此程序,然后使用args运行另一个副本,第一个副本将在断言检查
pthread\u cond\u signal()
时失败。 但是,将
open()
函数的顺序更改为
mmap()
“/data”
之前的
“/sync
”内存,所有操作都会正常工作

在我看来,这似乎是LynxOS中的一个主要错误,但LynuxWorks声称,POSIX标准不包括以这种方式在命名共享内存中使用互斥和条件变量,因此他们不感兴趣

有人能确定此代码是否确实违反POSIX吗?
或者是否有人有任何令人信服的文档证明它符合POSIX

Edit:我们知道
PTHREAD\u PROCESS\u SHARED
是POSIX,由LynxOS支持。争论的领域是互斥和信号量是否可以在命名共享内存中使用(正如我们所做的)或者,如果POSIX只允许在一个进程创建并映射共享内存,然后分叉第二个进程时使用它们。

该函数可用于允许共享内存中的pthread mutex被任何有权访问该内存的线程访问,甚至是不同进程中的线程。根据pthread\u mutex\u setpshared符合POSIX P1003.1c。(条件变量也是如此,请参见
pthread\u condattr\u setpshared


相关问题:

我可以很容易地看出PTHREAD\u PROCESS\u SHARED在操作系统级别上的实现是多么棘手(例如,MacOS没有,除了看起来像是rBlock)。但仅仅从阅读标准来看,你似乎有一个理由

为了完整性,您可能希望断言*_setpshared()函数调用的on和返回值-可能还有另一个“惊喜”在等着您(但我可以从您已经检查过的注释中看出,实际上支持共享)


@JesperE:您可能希望参考而不是HP文档。

可能在
pthread\u cond\t
中有一些指针(不带pshared),因此您必须将其放在两个线程/进程中相同的地址中。使用相同的有序MMAP,两个进程的地址可能相等

在glibc中,cond_t中的指针指向线程的线程描述符,拥有mutex/cond


您可以使用mmap的非空第一个参数控制地址。

谢谢@JesperE,我知道
pthread\u mutex\u setpshared
pthread\u PROCESS\u SHARED
是POSIX。我不认为LynuxWorks否认这一点。我认为争论更多的是关于我们创建互斥和condvar所在的共享内存的方式,例如,每个进程通过命名共享内存访问,而不是仅仅在一个进程中创建它,然后分叉来创建另一个。对不起,我读这个问题有点草率。手册页上说“这个选项允许任何访问互斥对象的线程对互斥对象进行操作