MacOS X,C:shm_open在后续运行中失败,错误13权限被拒绝
我试图使用shm_open和mmap以及一个信号量在macosx上的两个进程之间共享一块内存 我遇到的一个问题是,当我第二次运行程序a时,当我尝试调用shm_open()时,我会遇到权限错误MacOS X,C:shm_open在后续运行中失败,错误13权限被拒绝,macos,semaphore,shared-memory,mmap,Macos,Semaphore,Shared Memory,Mmap,我试图使用shm_open和mmap以及一个信号量在macosx上的两个进程之间共享一块内存 我遇到的一个问题是,当我第二次运行程序a时,当我尝试调用shm_open()时,我会遇到权限错误 #include "SharedMemory.h" #include <sys/mman.h> #include <sys/stat.h> #include <fcntl.h> #include <errno.h>
#include "SharedMemory.h"
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <semaphore.h>
#include <pthread.h>
#include <cassert>
void * run_task(void * context);
const char * mem_name = "/tmp/my_mem2";
const char * sem_name = "/tmp/my_sem2";
int gFileDescr = -1;
void * gSharedMemoryAddr = NULL;
size_t gSharedMemorySize = 0;
sem_t * gSharedMemorySemaphore = NULL;
typedef struct {
completion_proc_t callback;
void * context;
} CallbackAndContext;
void setupSharedMem(size_t mem_size)
{
assert(-1 == gFileDescr);
assert(NULL == gSharedMemoryAddr);
assert(NULL == gSharedMemorySemaphore);
gSharedMemorySize = mem_size;
gFileDescr = shm_open(mem_name, O_RDWR | O_CREAT, 0);
if (gFileDescr <= 0) {
printf("Error, shm_open failed %d %s\n", errno, strerror(errno));
cleanup();
exit(-1);
}
if (ftruncate(gFileDescr, mem_size)) {
printf("ftruncate failed %d %s\n", errno, strerror(errno));
cleanup();
exit(-1);
}
gSharedMemoryAddr = mmap(0, mem_size, PROT_WRITE, MAP_SHARED, gFileDescr, 0);
if (gSharedMemoryAddr == (void *)-1) {
gSharedMemoryAddr = NULL;
printf("Could not map the memory: %d %s\n", errno, strerror(errno));
cleanup();
exit(-1);
}
// open a semaphore to sync memory access.
gSharedMemorySemaphore = sem_open(sem_name, O_CREAT, 0644, 1);
assert(gSharedMemorySemaphore);
int semval;
sem_getvalue(gSharedMemorySemaphore, &semval);
printf("The value of the semaphore is: %d\n", semval);
sem_wait(gSharedMemorySemaphore);
}
void cleanup()
{
if (gSharedMemorySemaphore)
sem_post(gSharedMemorySemaphore);
if (gSharedMemorySemaphore)
sem_close(gSharedMemorySemaphore);
if (gSharedMemoryAddr)
munmap(gSharedMemoryAddr, gSharedMemorySize);
shm_unlink(mem_name);
sem_unlink(sem_name);
}
void askForTask(unsigned char value, completion_proc_t completionProc, void * context)
{
unsigned char * memptr = (unsigned char *) gSharedMemoryAddr;
memptr[0] = value;
CallbackAndContext * candc = (CallbackAndContext *)malloc(sizeof(CallbackAndContext));
candc->callback = completionProc;
candc->context = context;
pthread_t myThread;
pthread_create(&myThread, NULL, run_task, (void *)candc);
}
void * run_task(void * context)
{
CallbackAndContext * candc = (CallbackAndContext *)context;
completion_proc_t comp_proc = NULL;
void * callback_context = NULL;
if (candc) {
comp_proc = candc->callback;
callback_context = candc->context;
free(candc);
}
printf("My Task runner started.\n");
// this will cause the task to start.
if (sem_post(gSharedMemorySemaphore)) {
printf("Error posting to semaphore: %d %s\n", errno, strerror(errno));
cleanup();
exit(-1);
}
// wait for task to be done.
if (sem_wait(gSharedMemorySemaphore)) {
printf("Error acquiring semaphore: %d %s\n", errno, strerror(errno));
cleanup();
exit(-1);
}
printf("Task over\n");
if (comp_proc) {
comp_proc(callback_context);
}
return NULL;
}
#包括“SharedMemory.h”
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
void*运行任务(void*上下文);
const char*mem_name=“/tmp/my_mem2”;
const char*sem_name=“/tmp/my_sem2”;
int gFileDescr=-1;
void*gSharedMemoryAddr=NULL;
大小\u t gSharedMemorySize=0;
sem_t*gSharedMemorySemaphore=NULL;
类型定义结构{
完成过程回调;
无效*上下文;
}CallbackAndContext;
无效设置SharedMem(大小\u t成员大小)
{
断言(-1==gFileDescr);
断言(NULL==gSharedMemoryAddr);
断言(NULL==gsharedMemorySamphore);
gSharedMemorySize=内存大小;
gFileDescr=shm_open(mem_name,O_RDWR | O_CREAT,0);
if(gFileDescr callback=completionProc;
candc->context=context;
pthread_t myThread;
pthread_创建(&myThread,NULL,run_任务,(void*)candc);
}
void*运行任务(void*上下文)
{
CallbackAndContext*candc=(CallbackAndContext*)上下文;
完成程序完成程序=空;
void*callback\u context=NULL;
如果(candc){
comp_proc=candc->callback;
回调_context=candc->context;
免费(candc);
}
printf(“我的任务运行程序已启动。\n”);
//这将导致任务启动。
if(sem_post(gsharedmemory信号量)){
printf(“发送到信号量的错误:%d%s\n”,errno,strerror(errno));
清理();
出口(-1);
}
//等待任务完成。
if(sem_wait(gsharedmemory信号量)){
printf(“获取信号量时出错:%d%s\n”,errno,strerror(errno));
清理();
出口(-1);
}
printf(“任务结束\n”);
if(comp_proc){
comp_proc(回调上下文);
}
返回NULL;
}
在我的main.mm文件中,它如下所示:
#define SHARED_MEMORY_BLOCK_SIZE 5000
unsigned char gValue = 0;
extern void * gSharedMemoryAddr;
NSConditionLock * taskLock;
enum {
waiting
,done
};
void MyCompletionProc(void * context)
{
assert(gSharedMemoryAddr);
unsigned char * valPtr = (unsigned char *)gSharedMemoryAddr;
printf("Task Complete Callback: %s\n", gValue == valPtr[1] ? "success" : "fail" );
[taskLock lock];
[taskLock unlockWithCondition:done];
}
int main(int argc, const char * argv[])
{
taskLock = [[NSConditionLock alloc] initWithCondition: waiting];
setupSharedMem(SHARED_MEMORY_BLOCK_SIZE);
NSDate * start_time = [NSDate date];
for (;[[NSDate date] timeIntervalSinceDate:start_time] < 30.0f;) {
askForTask(++gValue, MyCompletionProc, NULL);
[taskLock lockWhenCondition:done];
[taskLock unlockWithCondition:waiting];
sleep(1);
}
cleanup();
return 0;
}
定义共享内存块大小5000
无符号字符gValue=0;
外部无效*gSharedMemoryAddr;
NSConditionLock*任务锁;
枚举{
等待
,完成
};
void MyCompletionProc(void*上下文)
{
断言(gSharedMemoryAddr);
unsigned char*valPtr=(unsigned char*)gSharedMemoryAddr;
printf(“任务完成回调:%s\n”,gValue==valPtr[1]?“成功”:“失败”);
[任务锁];
[taskLock unlockWithCondition:完成];
}
int main(int argc,const char*argv[]
{
taskLock=[[NSConditionLock alloc]initWithCondition:waiting];
setupSharedMem(共享内存块大小);
NSDate*开始时间=[NSDate日期];
对于(;[[NSDate-date]timeIntervalSinceDate:start\u-time]<30.0f;){
askForTask(++gValue,MyCompletionProc,NULL);
[条件:完成时任务锁锁定];
[任务锁解锁条件:等待];
睡眠(1);
}
清理();
返回0;
}
(希望在其中混用Objective-C不会让人困惑。)
我第一次运行程序时,它似乎可以正常工作,大约每秒调用一次askTask。30秒后,它调用“cleanup”并退出
在随后的运行中(除非我更改mem_name/sem_name的名称),我会收到一个权限错误。当我重新启动计算机直到下一次时,它会消失
我做错了什么?如何“重置”或防止它进入这种状态
后续:shm_unlink在cleanup()中失败,权限被拒绝。我不知道原因。已解决
问题是,当调用shm_open时,您需要指定一个“模式”,该模式为用户提供访问共享内存的权限,否则在取消链接时会出现权限错误
gFileDescr = shm_open(mem_name, O_RDWR | O_CREAT, 0);
gFileDescr = shm_open(mem_name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
我在这里找到了答案:解决了
问题是,当调用shm_open时,您需要指定一个“模式”,该模式为用户提供访问共享内存的权限,否则在取消链接时会出现权限错误
gFileDescr = shm_open(mem_name, O_RDWR | O_CREAT, 0);
gFileDescr = shm_open(mem_name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
我在这里找到了答案: