我在使用條件變量和互斥文件跨文件共享內存時遇到問題。即使設置爲PTHREAD_PROCESS_SHARED Pthread條件變量不發送信號
我的研究導致我到這裏Share condition variable & mutex between processes: does mutex have to locked before? 如果您運行兩個完全獨立的可執行文件,OP發佈的解決方案不起作用。我嘗試了他自己的方法來解決我自己的問題,而且兩個獨立的過程不會互相傳遞信號。因此,爲了確認OP代碼實際上起作用,如下所示,我複製了他的代碼,並在中途添加了一個#define,以便您可以編譯並作爲父親啓動,更改定義並作爲兒子啓動。 如果您使用OP運行代碼,只用叉子,它就可以工作。如果您以兩個獨立的可執行文件運行,則不起作用...... 有沒有人有任何想法?
背景問題 這個開始與我先前的問題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();
}
謝謝你這麼多@ALGOholic,我沒有看到那。所以我看到shm_open之後的子過程不需要ftruncate。那麼這意味着fttruncate在共享內存本身上運行,而不是確定單個進程虛擬地址空間的匹配大小? – Asvaldr
我看着它的方式 - shm_open()返回一個「文件」句柄,因此在邏輯上它應該表現爲+ - 作爲文件。 ftruncate()簡單地設置「文件」大小 - 與進程的虛擬內存無關。後一部分由mmap()調用處理,您可以在其中指定內存大小,並在虛擬內存頁面與其後備存儲(shm「文件」)之間建立鏈接。在幕後,內核爲mmap()調用識別共同的後備存儲,併爲這兩個進程分配相同的VM頁面。簡短的回答是 - 是的,ftruncate()在「shm」文件上運行,在兒子中不是必需的。 – ALGOholic