Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MacOS X,C:shm_open在后续运行中失败,错误13权限被拒绝_Macos_Semaphore_Shared Memory_Mmap - Fatal编程技术网

MacOS X,C:shm_open在后续运行中失败,错误13权限被拒绝

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>

我试图使用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 <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);
我在这里找到了答案: