有个项目需要在两个进程间用condition variable作同步。我的打算是将condition variable和mutex放入shared memory,然后分别映射到两个进程的空间,然后就像两个线程同步一样的操作。但是实际操作下来发现老是出现segmentation fault。
后来仔细研究了一下pthreads的condition variable和mutex,发现他们默认是不支持两个进程间的共享的,只能使用在同一个进程的多个线程之间。如果要使用,必须使用
pthread_mutexattr_setpshared()
pthread_condattr_setpshared()
两个函数将condition variable和mutex设置成PTHREAD_PROCESS_SHARED属性(默认的是PTHREAD_PROCESS_PRIVATE 属性)。
以下是我的测试程序。一共3个文件。
common.h:
- #ifndef __COMMON_H
-
#define __COMMON_H
-
-
#include <sys/mman.h>
-
#include <sys/stat.h> /* For mode constants */
-
#include <fcntl.h>
-
#include <unistd.h>
-
#include <sys/types.h>
-
#include <pthread.h>
-
#include <stdio.h>
-
-
//for shm_open()
-
#define SHARE_PATH "/leonshm"
-
#define SHARE_FLAG (O_RDWR | O_CREAT)
-
#define SHARE_MODE (0660)
-
//for ftruncate
-
#define SHARE_LEN (1024)
-
-
struct share_struct
-
{
-
pthread_cond_t cond;
-
pthread_mutex_t mutex;
-
int data;
-
};
-
-
-
#endif //__COMMON_H
producer.c
- /* -*- compile-command: "gcc -o producer producer.c -lrt" -*- */
-
/* set the data */
-
#include "common.h"
-
-
int
-
main()
-
{
-
int fd;
-
int i;
-
struct share_struct *shareinfo;
-
-
/* open posix shared memory */
-
fd = shm_open(SHARE_PATH, SHARE_FLAG, SHARE_MODE);
-
if (fd < 0) {
-
perror("shm_open");
-
return -1;
-
}
-
if (ftruncate(fd, SHARE_LEN) < 0) {
-
perror("ftruncate");
-
return -1;
-
}
-
/* map memory to process */
-
shareinfo = mmap(NULL, sizeof(struct share_struct), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
-
if (shareinfo < 0) {
-
perror("mmap");
-
return -1;
-
}
-
close(fd);
-
-
/* init struct */
-
/* by default, mutex and condition variable can not share between process, we have to enable this feature */
-
pthread_mutexattr_t mutexattr;
-
pthread_condattr_t condattr;
-
if (pthread_mutexattr_init(&mutexattr)) {
-
printf("error init mutex\n");
-
return -1;
-
}
- //以下两个设置非常关键
-
if (pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED)) {
-
printf("error mutex set shared\n");
-
return -1;
-
}
-
if (pthread_condattr_init(&condattr)) {
-
printf("error init condition var\n");
-
return -1;
-
}
-
if (pthread_condattr_setpshared(&condattr, PTHREAD_PROCESS_SHARED)) {
-
printf("error condition set shared\n");
-
return -1;
-
}
-
shareinfo->data = 0;
-
pthread_mutex_init(&shareinfo->mutex, &mutexattr);
-
pthread_cond_init(&shareinfo->cond, &condattr);
-
-
for (i = 1;; i++) {
-
pthread_mutex_lock(&shareinfo->mutex);
-
if (!shareinfo->data) {
-
shareinfo->data = i;
-
printf("producer, data set to:%d\n", shareinfo->data);
-
}
-
//printf("producer, running\n");
-
pthread_cond_broadcast(&shareinfo->cond);
-
pthread_mutex_unlock(&shareinfo->mutex);
-
//sleep(1);
-
}
-
-
if (shm_unlink(SHARE_PATH) < 0) {
-
perror("shm_unlink");
-
return -1;
-
}
-
pthread_mutexattr_destroy(&mutexattr);
-
pthread_condattr_destroy(&condattr);
-
-
return 0;
-
}
consumer.c
- /* -*- compile-command: "gcc -o consumer consumer.c -lrt" -*- */
-
/* clean the data */
-
#include "common.h"
-
-
int
-
main()
-
{
-
int fd;
-
struct share_struct *shareinfo;
-
-
/* open posix shared memory */
-
fd = shm_open(SHARE_PATH, SHARE_FLAG, SHARE_MODE);
-
if (fd < 0) {
-
perror("shm_open");
-
return -1;
-
}
-
if (ftruncate(fd, SHARE_LEN) < 0) {
-
perror("ftruncate");
-
return -1;
-
}
-
/* map memory to process */
-
shareinfo = mmap(NULL, sizeof(struct share_struct), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
-
if (shareinfo < 0) {
-
perror("mmap");
-
return -1;
-
}
-
close(fd);
-
-
while (1) {
-
pthread_mutex_lock(&shareinfo->mutex);
-
#if 1
-
while (!shareinfo->data) {
-
// printf("consumer, data:%d\n", shareinfo->data);
-
pthread_cond_wait(&shareinfo->cond, &shareinfo->mutex);
-
}
-
#endif
-
printf("consumer, cleaning data:%d\n", shareinfo->data);
-
shareinfo->data = 0;
-
pthread_mutex_unlock(&shareinfo->mutex);
-
//sleep(1);
-
}
-
-
if (shm_unlink(SHARE_PATH) < 0) {
-
perror("shm_unlink");
-
return -1;
-
}
-
-
return 0;
-
}
编译成producer和consumer两个可执行文件后先运行producer,然后运行consumer,这两个进程就可以同步了。
阅读(3264) | 评论(0) | 转发(0) |