从共享内存打印垃圾值

Posted

技术标签:

【中文标题】从共享内存打印垃圾值【英文标题】:print garbage values from the shared memory 【发布时间】:2016-03-14 16:18:43 【问题描述】:

我目前正在使用 C 实现生产者-消费者。

首先,我在用户进程中给定的可变长度的共享内存上创建一个缓冲区。

然后,在生产者进程中,我需要访问共享内存并将新数据放入缓冲区,以便消费者消费。

以下是消费者代码:

#include "common.h"
#include <unistd.h>

int fd;
int errno;
int MY_LEN = 0;
Shared* shared_mem;
char *job[4];


int setup_shared_memory()
    fd = shm_open(MY_SHM, O_CREAT | O_RDWR, 0666);
    if(fd == -1)
        printf("shm_open() failed\n");
        exit(1);
    
    ftruncate(fd, sizeof(Shared) + MY_LEN*sizeof(char *));


int attach_shared_memory()
    shared_mem = (Shared*)  mmap(NULL, sizeof(Shared) + MY_LEN*sizeof(char *), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if(shared_mem == MAP_FAILED)
        printf("mmap() failed\n");
        exit(1);
    
    return 0;


int init_shared_memory() 
    shared_mem->data = 0;
    int i;

    for(i = 0; i < shared_mem->length; i++)
    
        shared_mem->arr[i] = 0;
        //  shared_mem->arr[i] = (char *)calloc(1, sizeof(char*));
    

    sem_init(&(shared_mem->mutex), 1, 1);


int init_job()
    int i;
    for(i = 0; i < 4; i++)
    
        job[i] = (char *)malloc(sizeof(char *));
    


int take_a_job(int index)
    init_job();
    char *ds = strdup(shared_mem->arr[index]);
    job[0] = strtok(ds, "-");

    int i = 1;
    while(i < 4)
           
        job[i] = strtok(NULL, "-");
        i++;
    

    // remove the job from the buffer
    shared_mem->arr[index] = NULL;  


int consume_job(int index)
    printf("\nPrinter starts printing the job %s, %s pages from Buffer[%d]. The duration is %s seconds and the source is %s.\n",job[3], job[2], index, job[1], job[0]);
    sleep(atoi(job[1])); // sleep for job[1] seconds.


int main(int args, char *argv[]) 
    setup_shared_memory();
    attach_shared_memory();

    init_shared_memory();

    MY_LEN = atoi(argv[1]); // the first parameter following ./printer = the length of the buffer
    shared_mem->length = MY_LEN;
    //shared_mem->arr = (int*) &shared_mem->arr;

    int index = 1;

    *(shared_mem->arr) = "1-10-5-6";
    *(shared_mem->arr + 1) = "2-5-2-7";
    *(shared_mem->arr + 2) = "3-20-10-8";
    *(shared_mem->arr + 3) = "4-7-4-9";

    take_a_job(index);

    int i;
    for(i = 0; i < shared_mem->length; i++)
        printf("\n\n%d set %s\n", i, shared_mem->arr[i]);   
    

    consume_job(index);
    printf("\n\nHello second check\n\n");
    while (1) 

    return 0;

这里是生产者代码:

#include "common.h"

int fd;
Shared* shared_mem;
char *job;

int setup_shared_memory()
    fd = shm_open(MY_SHM, O_RDWR, 0666);
    if(fd == -1)
        printf("shm_open() failed\n");
        exit(1);
    


int attach_shared_memory()
    shared_mem = (Shared*) mmap(NULL, sizeof(Shared), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if(shared_mem == MAP_FAILED)
        printf("mmap() failed\n");
        exit(1);
    

    return 0;


int create_a_job(int args, char *argv[])
    int i;
    job = (char *)calloc(8, sizeof(char *));

    if(args != 5)
        return 0; //the parameters are not correctly formatted
    else
        for(i = 1; i < args; i++)
        
            if(i > 1) 
                strcat(job, "-");           
            strcat(job, argv[i]);                   
        
    
    strcat(job, "\0");
    printf("\nthe job is %s\n", job);


int put_a_job()
    printf("shared_mem->length is %d\n\n", shared_mem->length);
    int i;

    for(i = 0; i < shared_mem->length; i++)
    
        if(*(shared_mem->arr + i) == 0)
        
            //shared_mem->arr[i] = (char *)malloc(sizeof(job));
            //strcpy(shared_mem->arr[i], job);
            *(shared_mem->arr + i) = (char *)job;
            printf("\n\nThe index is %d\n", i);
            //printf("\n\nthe argument is %s at %d\n", job, i);
            return i;
        
    
    printf("\n\nThe index is %d\n", i);


int main(int args, char *argv[]) 
    setup_shared_memory();
    attach_shared_memory();

// create a job with the parameters
    int result = create_a_job(args, argv);
    if(result == 0)
    
        printf("Not the right parameters.\n");
        printf("Plase enter client ID, job duration, number of pages and job ID.\n");
        return 0;
    

    int i;
    put_a_job();

    for (i=0; i < shared_mem->length; i++) 
        printf("the argument is %s at %d\n", (char *)(shared_mem->arr + i), i);
    

    printf("\n\n");

    return 0;

common.h 文件是

#ifndef _INCLUDE_COMMON_H_
#define _INCLUDE_COMMON_H_

#include <stdlib.h> 
#include <stdio.h>
#include <unistd.h>

// from `man shm_open`
#include <sys/mman.h>
#include <sys/stat.h>        /* For mode constants */
#include <fcntl.h>           /* For O_* constants */
#include <string.h>

#include <semaphore.h>

#define MY_SHM "/JIT"

typedef struct 
    sem_t mutex;
    int data;
    int length; // the length of the buffer
    char *arr[0];
 Shared;

#endif //_INCLUDE_COMMON_H_

我首先运行 ./consumer 10 & 分配长度为 10 的缓冲区,然后运行 ​​./producer 1 2 3 4 将作业放入缓冲区并打印缓冲区,我得到了垃圾值

任何帮助将不胜感激!谢谢!

【问题讨论】:

【参考方案1】:

说明

*(shared_mem->arr + i) = (char *)job;

将指针作业存储到共享内存中,而不是指向的值。 也许您想使用strncpy。 你不能在进程之间共享内存地址,因为 Linux 使用virtual memory。简而言之,一个进程中的地址对于不同的进程无效。

请注意,您存在内存泄漏,因为您从未为分配的作业调用 free()

【讨论】:

我删除了这一行并将其替换为 shared_mem->arr[i] = (char *)malloc(sizeof(job));但它仍然打印垃圾值?为什么?? @Blackgirl5 阅读我的答案中的链接页面并研究如何在 Linux 上管理内存。然后一切都将是水晶。您不能在进程之间共享指针(地址)。

以上是关于从共享内存打印垃圾值的主要内容,如果未能解决你的问题,请参考以下文章

无法从另一个孩子读取一个孩子写入的共享内存

在另一个进程中访问共享内存缓冲区

python multiprocessing - 在进程之间共享类字典,随后从进程写入反映到共享内存

JVM系列之五:垃圾回收

java内存模型值synchronized和volatile

Java如何分配和回收内存?Java垃圾收集器如何工作?