POSIX线程的C API需要设置特殊标志,以便在共享内存之间共享互斥锁-请参阅sem_init()
。我不太清楚区别是什么,但我尝试在共享内存中使用C++ std::condition_variable时遇到了问题-出现了分段故障。我在C++文档或构造函数中没有看到任何提到这一点的内容。我想知道如何/是否可以在共享内存中使用C++线程互斥锁。下面是我的测试代码供参考。注意,squeue
只是一个简单的(POD)静态大小的循环队列,不相关的东西被省略:
#include <iostream>
#include <sys/mman.h>
#include <sys/stat.h> /* For mode constants */
#include <fcntl.h> /* For O_* constants */
#include "squeue.h"
#define SHM_FILENAME "/shimmy-foo"
#define SQUEUE_LENGTH 10
typedef struct {
squeue<int,SQUEUE_LENGTH> queue;
std::mutex mutex;
std::condition_variable_any condvar;
} SHM;
int main() {
int shm_fd = 0;
SHM * shm_ptr = NULL;
squeue<int,SQUEUE_LENGTH> * queue = NULL;
std::mutex * mutex;
std::condition_variable_any * condvar;
// Init SHM. ftruncate() will zero area.
if((shm_fd = shm_open(SHM_FILENAME, O_CREAT|O_RDWR|O_EXCL, S_IREAD|S_IWRITE)) == -1 ) {
fprintf (stderr, "Could not open shm object. %s\n", strerror(errno));
return errno;
}
else {
fprintf (stderr, "Open shm OK. %d\n", shm_fd);
}
ftruncate(shm_fd, sizeof(SHM));
// Connect the shmptr pointer to set to the shared memory area,
// with desired permissions
if((shm_ptr = (SHM*)mmap(0, sizeof(SHM), PROT_READ|PROT_WRITE, MAP_SHARED, shm_fd, 0)) == MAP_FAILED) {
fprintf (stderr, "Could not map shm. %s\n", strerror(errno));
return errno;
}
else {
fprintf(stderr, "Mapped shm OK. %p\n", shm_ptr);
}
// Create queue and mutex.
queue = new(&shm_ptr->queue) squeue<int,SQUEUE_LENGTH>();
mutex = new(&shm_ptr->mutex) std::mutex();
condvar = new(&shm_ptr->condvar) std::condition_variable_any();
srand(time(NULL));
while(true) {
cout << "Waiting on lock" << endl;
mutex->lock();
if(!queue->full()) {
int value = rand()%100;
queue->push(value);
cout << "Pushed " << value << endl;
} else {
cout << "Que is full!" << endl;
};
condvar->notify_all(); //Seg fault.
mutex->unlock();
sleep(1);
}
}