Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.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
C++ 如果在使用pthread\u PROCESS\u SHARED时不调用pthread\u mutex\u destroy会发生什么_C++_C_Linux_Pthreads_Mutex - Fatal编程技术网

C++ 如果在使用pthread\u PROCESS\u SHARED时不调用pthread\u mutex\u destroy会发生什么

C++ 如果在使用pthread\u PROCESS\u SHARED时不调用pthread\u mutex\u destroy会发生什么,c++,c,linux,pthreads,mutex,C++,C,Linux,Pthreads,Mutex,在Linux上,可以使用PTHREAD_PROCESS_shared属性在进程之间共享互斥,然后将互斥保存在一个映射文件中,该文件可能会被许多进程使用 这是一个执行上述工作的示例: For example, the following code implements a simple counting semaphore in a mapped file that may be used by many processes. /* sem.h */ struct semaphore {

在Linux上,可以使用PTHREAD_PROCESS_shared属性在进程之间共享互斥,然后将互斥保存在一个映射文件中,该文件可能会被许多进程使用

这是一个执行上述工作的示例:

For example, the following code implements a simple counting semaphore in a mapped file that may be used by many processes.

/* sem.h */
struct semaphore {
    pthread_mutex_t lock;
    pthread_cond_t nonzero;
    unsigned count;
};
typedef struct semaphore semaphore_t;

semaphore_t *semaphore_create(char *semaphore_name);
semaphore_t *semaphore_open(char *semaphore_name);
void semaphore_post(semaphore_t *semap);
void semaphore_wait(semaphore_t *semap);
void semaphore_close(semaphore_t *semap);

/* sem.c */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <pthread.h>
#include "sem.h"

semaphore_t *
semaphore_create(char *semaphore_name)
{
int fd;
    semaphore_t *semap;
    pthread_mutexattr_t psharedm;
    pthread_condattr_t psharedc;

    fd = open(semaphore_name, O_RDWR | O_CREAT | O_EXCL, 0666);
    if (fd < 0)
        return (NULL);
    (void) ftruncate(fd, sizeof(semaphore_t));
    (void) pthread_mutexattr_init(&psharedm);
    (void) pthread_mutexattr_setpshared(&psharedm,
        PTHREAD_PROCESS_SHARED);
    (void) pthread_condattr_init(&psharedc);
    (void) pthread_condattr_setpshared(&psharedc,
        PTHREAD_PROCESS_SHARED);
    semap = (semaphore_t *) mmap(NULL, sizeof(semaphore_t),
            PROT_READ | PROT_WRITE, MAP_SHARED,
            fd, 0);
    close (fd);
    (void) pthread_mutex_init(&semap->lock, &psharedm);
    (void) pthread_cond_init(&semap->nonzero, &psharedc);
    semap->count = 0;
    return (semap);
}

semaphore_t *
semaphore_open(char *semaphore_name)
{
    int fd;
    semaphore_t *semap;

    fd = open(semaphore_name, O_RDWR, 0666);
    if (fd < 0)
        return (NULL);
    semap = (semaphore_t *) mmap(NULL, sizeof(semaphore_t),
            PROT_READ | PROT_WRITE, MAP_SHARED,
            fd, 0);
    close (fd);
    return (semap);
}

void
semaphore_post(semaphore_t *semap)
{
    pthread_mutex_lock(&semap->lock);
    if (semap->count == 0)
        pthread_cond_signal(&semapx->nonzero);
    semap->count++;
    pthread_mutex_unlock(&semap->lock);
}

void
semaphore_wait(semaphore_t *semap)
{
    pthread_mutex_lock(&semap->lock);
    while (semap->count == 0)
        pthread_cond_wait(&semap->nonzero, &semap->lock);
    semap->count--;
    pthread_mutex_unlock(&semap->lock);
}

void
semaphore_close(semaphore_t *semap)
{
    munmap((void *) semap, sizeof(semaphore_t));
}
The following code is for three separate processes that create, post, and wait on a semaphore in the file /tmp/semaphore. Once the file is created, the post and wait programs increment and decrement the counting semaphore (waiting and waking as required) even though they did not initialize the semaphore.

/* create.c */
#include "pthread.h"
#include "sem.h"

int
main()
{
    semaphore_t *semap;

    semap = semaphore_create("/tmp/semaphore");
    if (semap == NULL)
        exit(1);
    semaphore_close(semap);
    return (0);
}

/* post */
#include "pthread.h"
#include "sem.h"

int
main()
{
    semaphore_t *semap;

    semap = semaphore_open("/tmp/semaphore");
    if (semap == NULL)
        exit(1);
    semaphore_post(semap);
    semaphore_close(semap);
    return (0);
}

/* wait */
#include "pthread.h"
#include "sem.h"

int
main()
{
    semaphore_t *semap;

    semap = semaphore_open("/tmp/semaphore");
    if (semap == NULL)
        exit(1);
    semaphore_wait(semap);
    semaphore_close(semap);
    return (0);
}
例如,下面的代码在一个映射文件中实现了一个简单的计数信号量,该文件可能被许多进程使用。
/*扫描电镜*/
结构信号量{
pthread_mutex_t lock;
pthread_cond_t非零;
无符号计数;
};
类型定义结构信号量信号量;
信号量\ t*信号量\创建(字符*信号量\名称);
信号量\ t*信号量\ u打开(字符*信号量\ u名称);
无效信号量\u post(信号量\u t*semap);
无效信号量\u等待(信号量\u t*semap);
无效信号量\u关闭(信号量\u t*semap);
/*扫描电镜c*/
#包括
#包括
#包括
#包括
#包括
#包括“sem.h”
信号量*
信号量\创建(字符*信号量\名称)
{
int-fd;
信号量*semap;
pthread_mutextatr_t psharedm;
pthread_condattr_t psharedc;
fd=开放(信号量名称,O|u RDWR | O|u CREAT | O|u EXCL,0666);
如果(fd<0)
返回(空);
(void)ftruncate(fd,sizeof(信号量_t));
(void)pthread_mutexattr_init(&psharedm);
(void)pthread_mutexattr_setpshared(&psharedm),
PTHREAD_进程_共享);
(void)pthread_condattr_init(&psharedc);
(void)pthread_condattr_setpshared(&psharedc),
PTHREAD_进程_共享);
semap=(信号量t*)mmap(NULL,sizeof(信号量t),
保护读取、保护写入、地图共享、,
fd,0);
关闭(fd);
(void)pthread_mutex_init(&semap->lock,&psharedm);
(void)pthread_cond_init(&semap->nonzero,&psharedc);
semap->count=0;
返回(semap);
}
信号量*
信号量\u打开(字符*信号量\u名称)
{
int-fd;
信号量*semap;
fd=打开(信号量名称,O_RDWR,0666);
如果(fd<0)
返回(空);
semap=(信号量t*)mmap(NULL,sizeof(信号量t),
保护读取、保护写入、地图共享、,
fd,0);
关闭(fd);
返回(semap);
}
无效的
信号量post(信号量t*semap)
{
pthread_mutex_lock(&semap->lock);
如果(语义映射->计数==0)
pthread_cond_信号(&semapx->非零);
semap->count++;
pthread_mutex_unlock(&semap->lock);
}
无效的
信号量等待(信号量t*semap)
{
pthread_mutex_lock(&semap->lock);
而(语义映射->计数==0)
pthread_cond_wait(&semap->nonzero,&semap->lock);
语义映射->计数--;
pthread_mutex_unlock(&semap->lock);
}
无效的
信号量\u关闭(信号量\u t*semap)
{
munmap((void*)semap,sizeof(semaphore_t));
}
以下代码用于创建、发布和等待文件/tmp/semaphore中的信号量的三个独立进程。创建文件后,post和wait程序会增加和减少计数信号量(根据需要等待和唤醒),即使它们没有初始化信号量。
/*创建.c*/
#包括“pthread.h”
#包括“sem.h”
int
main()
{
信号量*semap;
semap=semaphore\u create(“/tmp/semaphore”);
if(semap==NULL)
出口(1);
信号量_关闭(semap);
返回(0);
}
/*职位*/
#包括“pthread.h”
#包括“sem.h”
int
main()
{
信号量*semap;
semap=semaphore_open(“/tmp/semaphore”);
if(semap==NULL)
出口(1);
信号量_post(semap);
信号量_关闭(semap);
返回(0);
}
/*等等*/
#包括“pthread.h”
#包括“sem.h”
int
main()
{
信号量*semap;
semap=semaphore_open(“/tmp/semaphore”);
if(semap==NULL)
出口(1);
信号量等待(semap);
信号量_关闭(semap);
返回(0);
}
但是,在共享互斥体上调用pthread_mutex_destroy()非常棘手,因为它可能会在其他进程上导致错误,并且上面的示例也没有调用pthread_mutex_destroy()。所以我想不要破坏它

我的问题是:如果我初始化一个PTHREAD_进程_共享互斥体,将其保存到一个映射文件中,并在许多进程上永远使用它,而不调用PTHREAD_互斥体_destroy()或重新初始化它,那么安全吗

我的问题是:如果我初始化一个PTHREAD_进程_共享互斥体,将其保存到一个映射文件中,并在许多进程上永远使用它,而不调用PTHREAD_互斥体_destroy()或重新初始化它,那么安全吗

允许进程共享互斥比初始化它的进程长。如果您将这样一个互斥体映射到一个持久化的常规文件,那么它的状态将无限期地持久化,即使没有进程映射它。只要保持其状态的完整性——包括但不限于,没有进程通过
pthread\u mutex\u destroy()
销毁它——新进程就可以映射并使用它。也就是说,您描述的内容的语义是明确定义的

但它安全吗?不特别是

第一个问题是,您需要知道何时创建它,并且在创建时需要避免种族条件。如果您依赖于经常使用互斥体的进程在需要时对其进行初始化,那么您必须确保只有一个进程在文件不存在时创建并初始化互斥体

另一个问题是,使用这样一个长寿命的共享互斥体会产生大量的失败风险。例如,如果一个程序在保持互斥锁锁定时崩溃,那么它将保持锁定状态,直到您采取某种手动纠正措施。或者,如果直接操作映射文件,则互斥状态很容易损坏,在使用它的所有程序中产生未定义的行为,甚至在重新启动时也是如此

如果您确实需要一个长时间持久化的同步对象,那么我建议您考虑。设计时考虑了上述因素和其他因素。然而,它有些不同,因为这样的信号量驻留在内核中,并且具有内核持久性,因此它们不会在重新启动期间持久化(这通常是一件好事),并且它们不易受到普通文件操作的影响

或者,y