【问题标题】:String not displaying properly after being stored in shared memory字符串存储在共享内存后无法正常显示
【发布时间】:2014-12-25 22:16:54
【问题描述】:

我有一个充当缓冲区的数据结构。这是两个在其中具有 char *color 的结构。我可以自己从每个生产者进程中存储和检索正确的颜色,但消费者似乎没有看到颜色变量中的任何内容,尽管它知道它不为空。这怎么可能?

typedef struct {
    char *color;
    struct timeval time; 
} data_struct;

typedef struct{
    data_struct buf1;
    data_struct buf2;
} buffer;

在我存储的生产者中:

        ptr->buf1.color = color;
        gettimeofday (&tval, NULL);
        ptr->buf1.time = tval;

然后我可以打印它刚刚存储的颜色,并且它确实在同一个过程中工作。但消费者使用:

printf("%s\t", ptr->buf1.color);
struct timeval tval = ptr->buf1.time;
printf("%ld\n", (tval.tv_sec)*1000000L + tval.tv_usec);

最后他只是打印了一个空白区域,然后是一个标签,然后是时间(以秒为单位)。它如何访问相同的共享内存但看不到我的字符串?这个大致相同的代码在线程版本中工作得很好。感谢您的帮助!

使用共享内存段更新。

    int shmem_id;
    buffer *shmem_ptr;
    key_t key = 7484;
    int size = 2048; 
    int flag = 1023;

    char keystr[10];

    /* create a shared memory segment */
    shmem_id = shmget (key, size, flag);    
    shmem_ptr = shmat (shmem_id, (void *) NULL, 1023);
    shmem_ptr->buf1.color = NULL;
    shmem_ptr->buf2.color = NULL;
    sprintf (keystr, "%d", key);

【问题讨论】:

  • 什么是color的数据类型:ptr->buf1.color = color; ?
  • 颜色是 char *color;后来颜色=“红色”;我能够在结构中使用 strcpy 和 char color[8] 而不是使用指针来解决它,但我想知道这是否是唯一的方法。我在这里找到了解决方案:stackoverflow.com/questions/15534923/… 有趣的是,线程没有出现这些问题。
  • 我想到了两种可能性:(1)您是将数据放在共享内存段中还是分配它? (2) 两个进程是否都将共享段映射到同一个虚拟地址?如果不在第二个,消费者看到的指针将指向错误的位置。如果不清楚,我建议向我们展示映射共享内存和分配缓冲区的代码。

标签: c string fork semaphore strcpy


【解决方案1】:

我认为你没有正确分配结构和缓冲区的原因是它们没有受到保护,因此它会被任何东西覆盖。尝试执行以下操作:

 typedef struct {
   char *color;
    struct timeval time; 
} data_struct;


data_struct *temp=(data_struct*)malloc(sizeof(data_struct));

temp->color = (char *)malloc(strlen(color)+1);

strcpy(temp->color, color);

我认为这样做不会产生问题。但记得先释放分配的内存,先释放字符串再释放结构。

  free(temp->color);
  free(temp);

【讨论】:

    【解决方案2】:

    尽管buf 可能在共享内存中,但这并不能保证color 也指向共享内存中的某些内容。我的猜测是color 指向的地址只有生产者进程可见,消费者进程不可见。要解决此问题,您可以将 color 字段定义为固定长度的字符数组,并使用

    strncpy(ptr->buf1.color, color, BUFLEN);
    ptr->buf1.color[BUFLEN-1] = '\0';
    

    设置颜色。

    【讨论】:

      【解决方案3】:

      它不起作用,因为您有一个存储指针的进程和一个读取该指针的单独进程。但是这两个进程不共享同一个地址空间,所以读取的时候指针是没有意义的。您可以通过以下几种方式解决此问题:

      1. 使用线程而不是进程;这样,生产者和消费者将拥有一个单一的地址空间,并且来自一个地址空间的指针将在另一个地址空间中有效。
      2. 将文本直接存储在结构中,无需指针间接(即char color[30])。
      3. 在结构中存储一个“偏移指针”,并将字符数据存储在共享内存区域的其他位置(一种池分配器)。
      4. 在生产者和消费者中创建一个固定字符串数组,并将索引存储到该查找表中。如果事先知道字符串,则此方法有效。

      【讨论】:

      • 但我认为当你 fork 进程时,子进程继承了所有相同的内存项。
      猜你喜欢
      • 1970-01-01
      • 2015-06-11
      • 2011-01-06
      • 2012-03-09
      • 2021-12-26
      • 2014-04-27
      • 1970-01-01
      • 2014-11-18
      • 1970-01-01
      相关资源
      最近更新 更多