首页 文章

从共享内存中打印垃圾值

提问于
浏览
0

我目前正在使用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 回答

  • 3

    指令

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

    将指针作业存储到共享mem中,而不是指向的值 . 也许你想使用strncpy . 由于Linux使用virtual memory,因此无法在进程之间共享内存地址 . 为了简化故事,流程中的地址对于不同的流程无效 .

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

相关问题