2015-09-04 80 views
0

我想从可以从其他进程使用的子进程创建共享内存。但是,当我在子项中创建共享内存时,尝试在共享内存中使用指针时,父项崩溃。无法访问在子进程中创建的共享内存

#include <stdio.h> 
#include <unistd.h> 
#include <sys/mman.h> 

struct list_node 
{ 
    char *data; 
}; 

static int create_shared(void **pointer, int size) 
{ 
    *pointer = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0); 
    if(*pointer == MAP_FAILED) 
    { 
     perror("mmap:"); 
     return -1; 
    } 

    return 0; 
} 

int main(void) 
{ 
    int rtrn; 
    pid_t pid; 
    struct list_node *node; 

    pid = fork(); 
    if(pid == 0) 
    { 
     rtrn = create_shared((void **)&node, sizeof(struct list_node)); 
     if(rtrn < 0) 
     { 
      printf("Can't create shared node\n"); 
      return -1; 
     } 

     rtrn = asprintf(&node->data, "Test\n"); 
     if(rtrn < 0) 
     { 
      perror("asprintf:"); 
      return -1; 
     } 

     printf("data_child: %s\n", node->data); 
    } 
    else if(pid > 0) 
    { 
     /* Parent. */ 

     sleep(1); // Make sure child runs first. 

     printf("data_parent: %s\n", node->data); 
    } 
    else 
    { 
     perror("fork"); 
     return -1; 
    } 

    return 0; 
} 

但是当我创造它可以从孩子的过程中使用的父进程共享内存,它不只是一个副本,从fork()因为孩子可以改变指针和家长看的吧。在下面的示例中,孩子将node->data的值从测试更改为最佳。

#include <stdio.h> 
#include <unistd.h> 
#include <sys/mman.h> 

struct list_node 
{ 
    char *data; 
}; 

static int create_shared(void **pointer, int size) 
{ 
    *pointer = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0); 
    if(*pointer == MAP_FAILED) 
    { 
     perror("mmap:"); 
     return -1; 
    } 

    return 0; 
} 

int main(void) 
{ 
    int rtrn; 
    struct list_node *node; 

    rtrn = create_shared((void **)&node, sizeof(struct list_node)); 
    if(rtrn < 0) 
    { 
     printf("Can't create shared node\n"); 
     return -1; 
    } 

    rtrn = asprintf(&node->data, "Test\n"); 
    if(rtrn < 0) 
    { 
     perror("asprintf:"); 
     return -1; 
    } 

    pid_t pid; 

    pid = fork(); 
    if(pid == 0) 
    { 
     printf("data_child: %s\n", node->data); 

     node->data = "Best"; 
    } 
    else if(pid > 0) 
    { 
     /* Parent. */ 

     sleep(1); // Make sure child runs first. 

     printf("data_parent: %s\n", node->data); 
    } 
    else 
    { 
     perror("fork"); 
     return -1; 
    } 

    return 0; 
} 

那么如何从小孩创建共享内存以便父级或其他子进程可以访问它呢?

编辑

我想这标志着char *data点为共享内存create_shared()又名MMAP但是要打印的字符串时,我仍然得到段错误的char *data指向的内存。以下是我如何设置data作为共享内存。我也试过memcpy认为只是设置char *data来测试只是将指针设置为非共享内存,但这也不起作用。

rtrn = create_shared((void **)&node->data, 5); 
if(rtrn < 0) 
{ 
    printf("Can't create shared data\n"); 
    return -1; 
} 

node->data = "Test"; 
//memcpy(node->data, "Test", 4); 
+0

@Dmitri我认为您的权利关于重复,谢谢指出那篇文章。 – 2trill2spill

+0

此外,字符串'node-> data'指向需要在该(或另一个)共享内存区域内,否则父节点将无法访问它(即使它本身可以访问“节点”)。 – Dmitri

回答

0
char *data; 

您共享内存的一部分,但只包含一个指针。

它指向的位置对其他进程不可见。

分享字符串。或者,如果您知道它的最大长度,请使用字符数组而不是指针。


在第二个例子中,是"Best"字符串文字,并且将被放置在可执行文件中。你设置了指向这个地址的指针,并且由于两个进程使用相同的可执行文件,所以地址也会相同,并且指针将会有效。

注:我认为这是C标准的范围之外,我不知道什么是POSIX标准说这一点,所以它可能无法移植...