簡體   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