附加共享内存段时出错

时间:2016-11-08 13:48:41

标签: c debugging fork shared-memory

我有以下代码,我希望通过共享内存段在两个进程之间进行通信。我的问题是我在附加内存段时出错,我不知道为什么。

String

我引用了其他两个用于编译的文件。

process.h:

String sub = new String(new char[]{s.charAt(0), s.charAt(1)});

and process.c:

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
#include "process.h"

int main(int argc, char** argv)
{
    /*- Check the command-line arguments -*/
    if(argc != 2)
    {
        printf("\n--- Wrong input at command-line arguments ---\n\n");
        printf("--- The program terminate --- \n");
        return 1;
    }

    int N = atoi(argv[1]);      // The amount of total threads to be created
    int status;         // for the wait() function
    char* data;         // a string to use for shared memory segment

    /*- Variables for the shared memory segment -*/
    key_t key = 1003;       // for the shmget() key argument
    int shmid;          // to store the returned value from shmget()
    int size = 1024;        // for the shmget() size argument


/* ************************************************************************************/

    pid_t pid = fork(); // create second process

    if(pid < 0)     // if something going wrong
    {
        printf("\n\n---- Error in function fork!----\n");
        exit(1);
    }
    else if(pid == 0)   // the child process (P) 
    {
        // create the shared memory segment for the P process
        shmid = CreateShmSegment(key, size, IPC_CREAT);

        if(shmid == -1)     // check if creating shared memory return an error
        {
            printf("\n---Error at creating the memory segment! ---\n");
            exit(1);
        }

        // attach the shared memory segment
        data = AttachShmSegment(shmid);

        if(data == (char*)-1)   // check if attached the shared memory return an error
        {
            printf("\n---Error at attaching the memory segment! ---\n");
            exit(1);
        }   

        char* str = data;
        sprintf(str, "testing");

//      ChildProcess();
        printf("\n** Child process! ** \n");
        printf("N = %d\n", N);
        printf("write: %s\n",str);

        // detach the shared memory segment
        if(shmdt(data) == -1)       //check for error
        {
            printf("\n---Error at detaching memory segment! ---\n");
            exit(1);
        }
    }
    else            // the parent process (C)
    {   
        // create the shared memory segment for the C process
        shmid = CreateShmSegment(key, size, IPC_CREAT);

        if(shmid == -1)     // check if creating shared memory return an error
        {
            printf("\n---Error at creating the memory segment! ---\n");
            exit(1);
        }

        // attach the shared memory segment
        data = AttachShmSegment(shmid);
        if(data == (char*)-1)   // check if attached the shared memory return an error
        {
            printf("\n---Error at attaching the memory segment! ---\n");
            exit(1);
        }   

//      ParentProcess();
        wait(&status);
        printf("\n** Parent process! **\n");
        printf("N = %d\n",N);   
        printf("read from segment: %s\n", data);

        // detach the shared memory segment
        if(shmdt(data) == -1)       //check for error
        {
            printf("\n---Error at detaching memory segment! ---\n");
            exit(1);
        }

        // deallocate the shared memory segment
        if(DeallocateShmSegment(shmid) == -1)   //check for error
        {
            printf("\n---Error at destroy memory segment! ---\n");
            exit(1);
        }
    }

    return 0;
}

我不知道连接内存会出现什么问题。我在网上搜索并对shmat()的参数进行了一些更改,但我无法解决它。

3 个答案:

答案 0 :(得分:1)

创建细分时,您没有指定任何模式标志。因此,我希望它对任何人(包括其创建者)都不具有读取或写入访问权限。这本身并不是错误的,但是在具有该模式的情况下,非特权进程尝试附加该段的所有尝试都将失败EACCES

据推测,您希望在创建段时在标志中包含至少S_IRWXU,或者在事实之后使用shmctl()来修改段的模式以允许对该段的读写访问权限所有者。 (请注意,执行权限对于此目的毫无意义,因此它等同于使用S_IRUSR | S_IWUSR。)例如,

    shmid = CreateShmSegment(key, size, IPC_CREAT | S_IRWXU);

您可能希望授予更广泛的访问权限。

另请注意,首先进行fork,然后让父进程和子进程都创建并附加共享内存段是很奇怪的。附加的共享内存段在fork()之间继承,因此在分叉之前创建和附加段会更清晰。

答案 1 :(得分:0)

这里的问题是你试图在两个进程中获得shmid,当两个进程调用CreateShmSegment()时,他们得到了不同的shmid,这就是他们失败的原因。

在fork()之前调用CreateShmSegment()和AttachShmSegment()。

答案 2 :(得分:0)

这种路线:

shmid = CreateShmSegment(key, size, IPC_CREAT); 

不正确,应该类似于:

shmid = CreateShmSegment(key, size, IPC_CREAT|0666);

为每个人提供读/写权限(在本例中)

一旦创建了共享内存段(没有适当的权限),那么您/用户将不得不销毁共享内存。列出共享内存使用:

ipcs -m 

在结果列表中

那些dest的人不再使用,应该被销毁。

权限列中的0也需要销毁。

你可以通过以下方式销毁共享内存:

ipcrm shm 32768 

其中32768是共享内存ID,取自列表

在代码更正问题和“坏”共享内存被破坏后输出代码:

** Child process! ** 
N = 2
write: testing

** Parent process! **
N = 2
read from segment: testing