繁体   English   中英

共享 Memory 和信号量:意外的分段错误

[英]Shared Memory and semaphores: Unexpected segmantation fault

我正在尝试创建 2 个由生产者和消费者组成的程序。 生产者生成一组从 0 到 9 的随机数,并将它们存储在共享 memory 中的 circular_queue 中,然后消费者从共享 memory 中读取队列并打印从 0 到 9 中每个数字的频率。

制作人没有给我错误。 但是,当我尝试运行消费者时,程序立即给出了分段错误。 我希望有人能检测出问题所在。 我还想知道是否有任何方法可以检查 dev/shm 目录以验证我尝试创建的共享 memory 文件是否正常工作? 谢谢

制片人

#include <fcntl.h>
#include <math.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <semaphore.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
#include "cola_circular.c"

#define SHM_NAME "/shm_eje4"
#define QUEUE_SIZE 10

typedef struct {
    circular_queue queue;
    sem_t sem_mutex;
} ShmStruct;

int main(int argc, char *argv[]) {
    int fd_shm;
    int i;
    pid_t ppid = 0;
    pid_t pid = 0;
    ShmStruct *input;

    if (argc < 3) {
        fprintf(stderr,"usage: %s <n_numbers> <generation_method>", argv[0]);
        return EXIT_FAILURE;
    } else {
        if (atoi(argv[1]) < 0) {
            fprintf(stderr,"<n_numbers> has to be greater than or equal to 0");
            return EXIT_FAILURE;
        }
        if (atoi(argv[2]) < 0 || atoi(argv[2]) > 1) {
            fprintf(stderr,"<generation_method>: 0 for random, 1 for sequential");
            return EXIT_FAILURE;
        }
    }

    /* Crear memoria compartida para la cola, semafaros */
    fd_shm = shm_open(SHM_NAME,
         O_RDWR | O_CREAT | O_EXCL,
          S_IRUSR | S_IWUSR);
    if  (fd_shm == -1) {
        fprintf(stderr, "Error creating the shared memory segments");
        shm_unlink(SHM_NAME);
        return EXIT_FAILURE;
    }

    /* Cambiar el tamaño del segmento de memoria */
    if (ftruncate(fd_shm, sizeof(ShmStruct)) == -1) {
        fprintf(stderr, "Error resizing the shared memory segment\n");
        shm_unlink(SHM_NAME);
        close(fd_shm);
        return EXIT_FAILURE;
    }

    /* Mapear el segmento de memoria */
    input = mmap(NULL,
         sizeof(*input),
         PROT_READ | PROT_WRITE, MAP_SHARED,
         fd_shm,
         0);
    close(fd_shm);
    if (input == MAP_FAILED) {
        fprintf(stderr, "Error mapping the shared memory segment\n");
        shm_unlink(SHM_NAME);
        close(fd_shm);
        return EXIT_FAILURE;
    }

    if (sem_init(&(input->sem_mutex),1,1) < 0) {
        fprintf(stderr, "Error initializing mutex semaphore\n");
        perror("sem_init");
        return EXIT_FAILURE;
    }
    input->queue = queue_ini(QUEUE_SIZE);

    /*Generamos N numeros aleatorios/secuencia entre 0 y 9*/
    sem_wait(&(input->sem_mutex));
    if (argv[2] == 0) {
        for (i=0; i<atoi(argv[1]); i++) {
            insert_queue(input->queue, rand()%10);
        }
    } else if (atoi(argv[2]) == 1) {
        for (i=0; i<atoi(argv[1]); i++) {
            insert_queue(input->queue, i%10);
        }
    }
    sem_post(&(input->sem_mutex));

    /*El programa espera un caracter mientras ejecutamos el hijo*/
    getchar();

    sem_destroy(&(input->sem_mutex));
    munmap(input, sizeof(*input));
    shm_unlink(SHM_NAME);
    close(fd_shm);
    return EXIT_SUCCESS;
} 

消费者

 #include <errno.h>
 #include <fcntl.h>
 #include <math.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <semaphore.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <time.h>
 #include <unistd.h>
 #include "cola_circular.c"

 #define SHM_NAME "/shm_eje4"

 typedef struct {
     circular_queue queue;
     sem_t sem_mutex;
 } ShmStruct;

 int  main(void) {
     fprintf(stdout, "1");
     int i;
     int count[10];
     int fd_shm = shm_open(SHM_NAME,
        O_RDONLY,
        0);
    if (fd_shm == -1) {
        fprintf(stderr, "Error opening the shared memory segment\n");
        return EXIT_FAILURE;
    }

    ShmStruct *output = mmap(NULL,
        sizeof(*output),
        PROT_READ,
        MAP_SHARED,
        fd_shm,
        0);
    close(fd_shm);
    if (output == MAP_FAILED) {
        fprintf(stderr, "Error mapping the shared memory segment\n");
        return EXIT_FAILURE;
    }

    sem_wait(&(output->sem_mutex));
    for (i=0; i<10; i++) {
        count[i] = 0;
    }
    for (i=0; i<output->queue.num; i++) {
        count[output->queue.queue[i]]++;
    }
    fprintf(stdout, "Histograma de numeros de queue:\n");
    for  (i=0; i<10; i++) {
        fprintf(stdout, "%d ---> %d\n", i, count[i]);
    }
    sem_post(&(output->sem_mutex));

    munmap(output, sizeof(*output));
    close(fd_shm);
    return EXIT_SUCCESS;
 }

循环队列

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

#define SIZE 124

typedef struct circular_queue {
    int *queue;
    int rear;
    int front;
    int size;
    int num;
} circular_queue;

circular_queue queue_ini(int size) {
    int i;
    circular_queue ret;
    ret.queue = (int*) malloc(0);
    ret.rear = -1;
    ret.front = -1;
    ret.size = size;
    ret.num = 0;
    return ret;
}

int queue_isFull(circular_queue queue) {
    if (queue.num == queue.size) {
        return 1;
    } else {
        fprintf(stderr, "Error inseting, the queue is full.\n");
        return 0;
    }
}

int insert_queue(circular_queue queue, int num) {
    if (queue_isFull(queue) == 1) {
        return 0;
    }
    ret.queue = (int*) realloc(ret.queue, sizeof(int)*(ret.num+1));
    if (queue.front == -1) queue.front = 0;
    queue.rear = (queue.rear+1)%SIZE;
    queue.queue[queue.rear] = num;
    queue.num++;
    fprintf(stdout, "\n Inserted --> %d", queue.num);
    return 1;
}

int queue_isEmpty(circular_queue queue) {
    if  (queue.num == 0) return 1;
    return 0;
}
ret.queue = (int*) realloc(sizeof(int)*(ret.num+1));

realloc function不分配共享memory。如果你不把队列放在共享memory,它是不共享的。 当您尝试从另一个进程访问指向一个进程中分配的常规 memory 的指针时,最常见的结果是崩溃。

您需要将所有共享数据放在共享 memory 中。当您跨进程共享指针时,您需要将一个相对指针共享到共享 memory 中,并且每个进程需要通过添加其特定基址将其转换为在其地址空间中有效的指针共享 memory 段的地址。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM