gpt4 book ai didi

c++ - 即使设置为 PTHREAD_PROCESS_SHARED,Pthread 条件变量也不会发出信号

转载 作者:太空狗 更新时间:2023-10-29 12:12:59 26 4
gpt4 key购买 nike

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

我的研究让我来到这里 Share condition variable & mutex between processes: does mutex have to locked before?如果您运行两个完全独立的可执行文件,OP 发布的解决方案将不起作用。我尝试了他的方法来解决我自己的问题,但两个单独的进程不会相互发出信号。因此,为了确认 OP 代码确实有效,如下所示,我复制了他的代码并在中途添加了#define,以便您可以编译并作为父亲启动,更改定义并作为儿子启动。如果你像 OP 那样用 fork 运行代码,它就可以工作。如果你作为两个单独的可执行文件运行,它就不起作用......有人有什么想法吗?

背景问题这始于我之前的问题 POSIX Shared Memory Sync Across Processes 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 互斥锁和条件变量初始化共享内存,然后在子进程中使用 O_TRUNC 销毁 pthreads 放入其中的所有内容。正确代码如下:

父亲.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);
}

儿子.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!!!!!!!!
$

关于c++ - 即使设置为 PTHREAD_PROCESS_SHARED,Pthread 条件变量也不会发出信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35448835/

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