c - 访问共享内存中的结构后出现段错误?

标签 c struct posix shared-memory

我在跨进程共享存储在 struct 中的值时遇到问题。下面我的代码被简化为只有一个过程,这将增加值 num2。每当进程结束时,waitpid() 将进程的pid 写入数组。这再次被简化,在我更大的项目中,我有大约 100 个进程,它们依次将它们的 pid 写入数组。所以每个进程都会看到数组。但是,对于它们中的每一个,struct 中的整数值都是不同的。为什么?

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <semaphore.h>
#include <sys/shm.h>

typedef struct{
   int num;
   int num1;
   int num2;
   char *array;
} data;

void c_print(data *a);

int main(int argc, char *argv[])
{
   data *main_data;

   int pam_id=shmget(IPC_PRIVATE,sizeof(data), IPC_CREAT | IPC_EXCL | 0666);
   if (pam_id == -1)
       fprintf(stderr,"error");
   int k=shmat(pam_id,NULL,0);
   if (k==NULL)
       fprintf(stderr,"shmat error");
   main_data=malloc(sizeof(data));
   main_data->num = strtol(argv[1],NULL,10);
   main_data->num1 = strtol(argv[2],NULL,10);
   main_data->num2 = strtol(argv[3],NULL,10);

如果下面没有 malloc,访问 main_data 会导致 segfault。但是,其他进程看不到存储在 struct 中的变量,除了数组。

  main_data->array = malloc(main_data->num2*sizeof(char));

  main_data->array[0]=fork();
  if (main_data->array[0]==0){
      main_data->num2+=2;
      exit(9);
  } else {
      waitpid(-1,main_data->array[0],0);
      c_print(main_data);
      return 0;
  }
  return 50;
}

最佳答案

您应该使用 k 而不是 malloc()k 的地址在进程之间共享。我认为您误解了 shm api。即,将 main_data->array=...; 替换为 main_data->array=(void*)k; 每个进程都会得到一份新的 main_data 。您需要将 shmgetnum2*sizeof(char) 一起使用。

您希望共享的内存应该使用shmget()shmat()malloc() 将按进程分配,并将使用父内存的副本进行初始化。如果 numnum1num2 是 private 或 const,那么你的 data结构可以使用malloc(),数组应该使用shgetshmat。如果您需要在所有进程中都动态更新,那么两者都必须使用 shget()shmat()

此外,您应该注意数据竞争。

关于c - 访问共享内存中的结构后出现段错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16123382/

相关文章:

在c中将字符串转换为int

c - 隐藏 GCC 警告 "set but not used"?

c++ - 如何从 operator new 或 malloc 为 mremap 获取页对齐内存

multithreading - 通过 POSIX 信号终止 C++11 中的多线程应用程序

c - 大小 8 valgrind 的无效写入

c - 如何获得 2^100 * 3^3 模 1000000007 的结果

读取垃圾内存会破坏程序流程吗?

arrays - Go接口(interface) slice 和指针

c - 在 C 中初始化包含函数指针的结构

iphone - 我们可以在 iPhone 中使用 POSIX 套接字吗