[英]Initializing shared memory safely
我有幾個進程通過OS X上的POSIX共享內存相互通信。我的問題是這些進程可能以任何順序生成,並嘗試同時初始化共享內存段。
我嘗試將咨詢鎖與fcntl
和flock
一起使用,但都無法告訴我我傳遞了無效的文件描述符(我肯定文件描述符不是無效的)。 顯然,這是不可能的。
有其他選擇嗎? 還是有我不知道的有關對共享內存使用鎖的任何詳細信息?
編輯:我嘗試使用鎖看起來像這樣:
// Some declarations...
struct Queue {
int index[ENTRIES_PER_QUEUE];
sem_t lock;
sem_t readWait;
sem_t writeSem;
struct Entry slots[ENTRIES_PER_QUEUE];
};
struct ipc_t {
int fd;
char name[512];
struct Queue* queue;
};
ipc_t ipc_create(const char* name, int owner) {
int isInited = 1;
struct Queue* queue;
struct flock lock = {
.l_type = F_WRLCK,
.l_whence = SEEK_SET,
.l_start = 0,
.l_len = 0
};
ipc_t conn = malloc(sizeof(struct ipc_t));
sprintf(conn->name, "/arqvenger_%s", name);
conn->fd = shm_open(conn->name, O_CREAT | O_RDWR, 0666);
if (conn->fd == -1) {
free(conn);
perror("shm_open failed");
return NULL;
}
if (fcntl(conn->fd, F_SETLKW, &lock) == -1) {
perror("Tanked...");
}
// Do stuff with the lock & release it
我得到的輸出是:
Tanked...: Bad file descriptor
一種常見的技術是首先使用O_CREAT|O_EXCL
調用shm_open
。 這僅對隨后必須進行設置的一個過程成功。 然后其他人將不得不像以前一樣進行打開操作,並稍等一會兒(可能是輪詢)安裝完成。
編輯:顯示如何如評論中所述工作。
struct head {
unsigned volatile flag;
pthread_mutex_t mut;
};
void * addr = 0;
/* try shm_open with exclusive, and then */
if (/* we create the segment */) {
addr = mmap(something);
struct head* h = addr;
pthread_mutex_init(&h->mut, aSharedAttr);
pthread_mutex_lock(&h->mut);
h->flag = 1;
/* do the rest of the initialization, and then */
pthread_mutex_unlock(&h->mut);
} else {
/* retry shm_open without exclusive, and then */
addr = mmap(something);
struct head* h = addr;
/* initialy flag is guaranteed to be 0 */
/* this will break out of the loop whence the new value is written to flag */
while (!h->flag) sched_yield();
pthread_mutex_lock(&h->mut);
pthread_mutex_unlock(&h->mut);
}
我已經能夠重現該問題。 然后我在標准中發現一個可悲的發現:
當文件描述符fildes引用共享內存對象時,fcntl()的行為應與常規文件相同,不同之處在於未指定參數cmd的以下值的影響:F_SETFL,F_GETLK,F_SETLK和F_SETLKW 。
因此很可能尚不支持。 對於這樣一個簡單的設置,我將使用信號量來表示“內存已准備就緒”。
似乎我需要提及的是可以使用“ O_EXCL”創建信號量(因此不存在種族)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.