Pthread条件变量不是信令,即使设置为PTHREAD_PROCESS_SHARED [英] Pthread Condition Variables not Signalling even though set to PTHREAD_PROCESS_SHARED

查看:1446
本文介绍了Pthread条件变量不是信令,即使设置为PTHREAD_PROCESS_SHARED的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用条件变量和跨文件互斥体时遇到共享内存问题。

I'm having trouble with shared memory using condition variables and mutexes accross files.

我的研究让我来到这里共享条件变量&进程之间的互斥:互斥是否必须锁定?
OP发布的解决方案,如果你运行两个完全独立的可执行文件不工作。我试着他的方法对我自己的问题和两个单独的过程,只是不会相互信号。所以确认OPs代码实际上是工作,如下所示我已经复制他的代码,并添加了一个#define中途,使您可以编译和启动作为父亲,更改define和开始作为儿子。
如果你运行的代码,OP只有一个fork,它的工作原理。如果你运行为两个独立的可执行文件它不工作......
有没有任何想法?

My research led me to here Share condition variable & mutex between processes: does mutex have to locked before? The solution that the OP posted, doesn't work if you run two completely separate executables. I tried his methods towards my own problem and two seperate processes just would not signal to each other. So to confirm that the OPs code actually works, as seen below i have copied his code and added a #define midway so that you can compile and start as the father, change the define and start as the son. If you run the code as the OP had it with just a fork, it works. if you run as two seperate executables it doesn't work...... Does anyone have any ideas?

背景问题
这开始于我上一个问题 POSIX共享内存同步跨进程C ++ / C ++ 11

测试代码

#include <QCoreApplication>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>

#define OKTOWRITE "/condwrite"
#define MESSAGE "/msg"
#define MUTEX "/mutex_lock"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    pthread_cond_t* condition;
    pthread_mutex_t* mutex;
    char* message;
    int des_cond, des_msg, des_mutex;
    int mode = S_IRWXU | S_IRWXG;

    des_mutex = shm_open(MUTEX, O_CREAT | O_RDWR | O_TRUNC, mode);

    if (des_mutex < 0) {
        perror("failure on shm_open on des_mutex");
        exit(1);
    }

    if (ftruncate(des_mutex, sizeof(pthread_mutex_t)) == -1) {
        perror("Error on ftruncate to sizeof pthread_cond_t\n");
        exit(-1);
    }

    mutex = (pthread_mutex_t*) mmap(NULL, sizeof(pthread_mutex_t),
            PROT_READ | PROT_WRITE, MAP_SHARED, des_mutex, 0);

    if (mutex == MAP_FAILED ) {
        perror("Error on mmap on mutex\n");
        exit(1);
    }

    des_cond = shm_open(OKTOWRITE, O_CREAT | O_RDWR | O_TRUNC, mode);

    if (des_cond < 0) {
        perror("failure on shm_open on des_cond");
        exit(1);
    }

    if (ftruncate(des_cond, sizeof(pthread_cond_t)) == -1) {
        perror("Error on ftruncate to sizeof pthread_cond_t\n");
        exit(-1);
    }

    condition = (pthread_cond_t*) mmap(NULL, sizeof(pthread_cond_t),
            PROT_READ | PROT_WRITE, MAP_SHARED, des_cond, 0);

    if (condition == MAP_FAILED ) {
        perror("Error on mmap on condition\n");
        exit(1);
    }

//#define father
#ifdef father


    /* HERE WE GO */
    /**************************************/

        /* set mutex shared between processes */
    pthread_mutexattr_t mutexAttr;
    pthread_mutexattr_init(&mutexAttr);
    pthread_mutexattr_setpshared(&mutexAttr, PTHREAD_PROCESS_SHARED);
    pthread_mutex_init(mutex, &mutexAttr);

    /* set condition shared between processes */
    pthread_condattr_t condAttr;
    pthread_condattr_init(&condAttr);
    pthread_condattr_setpshared(&condAttr, PTHREAD_PROCESS_SHARED);
    pthread_cond_init(condition, &condAttr);

    /*************************************/


    printf("father waits on condition\n");

     pthread_mutex_lock(mutex);
     pthread_cond_wait(condition, mutex);
     pthread_mutex_unlock(mutex);

     printf("Signaled by son process, wake up!!!!!!!!\n");

    pthread_condattr_destroy(&condAttr);
    pthread_mutexattr_destroy(&mutexAttr);
    pthread_mutex_destroy(mutex);
    pthread_cond_destroy(condition);

    shm_unlink(OKTOWRITE);
    shm_unlink(MESSAGE);
    shm_unlink(MUTEX);
#else

//    if (!fork()) {

//        sleep(3);

        pthread_mutex_lock(mutex);
        pthread_cond_signal(condition);
        printf("son signaled\n");
        pthread_mutex_unlock(mutex);
        exit(0);
//    }

//    else {

#endif

//    }

    exit(0);

    return a.exec();
}


推荐答案

内存用于在子进程中不必要地互斥和条件变量。因为这个部分以前发生在fork()之前的原始代码中,你只做一次对夫妇。但在两个单独的进程中,你分别在父中使用跨进程的pthread mutex和条件变量来初始化共享内存,然后通过在子进程中使用O_TRUNC来破坏pthreads中放置的所有内容。正确的代码如下:

You're truncating the shared memory for mutex and conditional variable unnecessarily in the son process. Since this part used to happen before fork() in the original code you were doing it only once for the couple. But in two separate processes you're initializing the shared memory with cross-process pthread mutex and conditional variable respectively in father and then destroying everything that pthreads put in there by using O_TRUNC in the son. The correct code is following:

father.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>

#define OKTOWRITE "/condwrite"
#define MESSAGE "/msg"
#define MUTEX "/mutex_lock"

int main(int argc, char *argv[])
{
    pthread_cond_t* condition;
    pthread_mutex_t* mutex;
    char* message;
    int des_cond, des_msg, des_mutex;
    int mode = S_IRWXU | S_IRWXG;

    des_mutex = shm_open(MUTEX, O_CREAT | O_RDWR | O_TRUNC, mode);

    if (des_mutex < 0) {
        perror("failure on shm_open on des_mutex");
        exit(1);
    }

    if (ftruncate(des_mutex, sizeof(pthread_mutex_t)) == -1) {
        perror("Error on ftruncate to sizeof pthread_cond_t\n");
        exit(-1);
    }

    mutex = (pthread_mutex_t*) mmap(NULL, sizeof(pthread_mutex_t),
            PROT_READ | PROT_WRITE, MAP_SHARED, des_mutex, 0);

    if (mutex == MAP_FAILED ) {
        perror("Error on mmap on mutex\n");
        exit(1);
    }

    des_cond = shm_open(OKTOWRITE, O_CREAT | O_RDWR | O_TRUNC, mode);

    if (des_cond < 0) {
        perror("failure on shm_open on des_cond");
        exit(1);
    }

    if (ftruncate(des_cond, sizeof(pthread_cond_t)) == -1) {
        perror("Error on ftruncate to sizeof pthread_cond_t\n");
        exit(-1);
    }

    condition = (pthread_cond_t*) mmap(NULL, sizeof(pthread_cond_t),
            PROT_READ | PROT_WRITE, MAP_SHARED, des_cond, 0);

    if (condition == MAP_FAILED ) {
        perror("Error on mmap on condition\n");
        exit(1);
    }

    /* HERE WE GO */
    /**************************************/

        /* set mutex shared between processes */
    pthread_mutexattr_t mutexAttr;
    pthread_mutexattr_init(&mutexAttr);
    pthread_mutexattr_setpshared(&mutexAttr, PTHREAD_PROCESS_SHARED);
    pthread_mutex_init(mutex, &mutexAttr);

    /* set condition shared between processes */
    pthread_condattr_t condAttr;
    pthread_condattr_init(&condAttr);
    pthread_condattr_setpshared(&condAttr, PTHREAD_PROCESS_SHARED);
    pthread_cond_init(condition, &condAttr);

    /*************************************/


    printf("father waits on condition\n");

     pthread_mutex_lock(mutex);
     pthread_cond_wait(condition, mutex);
     pthread_mutex_unlock(mutex);

     printf("Signaled by son process, wake up!!!!!!!!\n");

    pthread_condattr_destroy(&condAttr);
    pthread_mutexattr_destroy(&mutexAttr);
    pthread_mutex_destroy(mutex);
    pthread_cond_destroy(condition);

    shm_unlink(OKTOWRITE);
    shm_unlink(MESSAGE);
    shm_unlink(MUTEX);

    exit(0);
}

son.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>

#define OKTOWRITE "/condwrite"
#define MESSAGE "/msg"
#define MUTEX "/mutex_lock"

int main(int argc, char *argv[])
{
    pthread_cond_t* condition;
    pthread_mutex_t* mutex;
    char* message;
    int des_cond, des_msg, des_mutex;
    int mode = S_IRWXU | S_IRWXG;

    des_mutex = shm_open(MUTEX, O_CREAT | O_RDWR, mode);

    if (des_mutex < 0) {
        perror("failure on shm_open on des_mutex");
        exit(1);
    }

    mutex = (pthread_mutex_t*) mmap(NULL, sizeof(pthread_mutex_t),
            PROT_READ | PROT_WRITE, MAP_SHARED, des_mutex, 0);

    if (mutex == MAP_FAILED ) {
        perror("Error on mmap on mutex\n");
        exit(1);
    }

    des_cond = shm_open(OKTOWRITE, O_CREAT | O_RDWR, mode);

    if (des_cond < 0) {
        perror("failure on shm_open on des_cond");
        exit(1);
    }

    condition = (pthread_cond_t*) mmap(NULL, sizeof(pthread_cond_t),
            PROT_READ | PROT_WRITE, MAP_SHARED, des_cond, 0);

    if (condition == MAP_FAILED ) {
        perror("Error on mmap on condition\n");
        exit(1);
    }

    pthread_mutex_lock(mutex);
    pthread_cond_signal(condition);
    printf("son signaled\n");
    pthread_mutex_unlock(mutex);
    exit(0);
}

测试:

1st terminal: $ ./father
father waits on condition

2nd terminal: $ ./son
son signaled

1st terminal: Signaled by son process, wake up!!!!!!!!
$

这篇关于Pthread条件变量不是信令,即使设置为PTHREAD_PROCESS_SHARED的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆