簡體   English   中英

與結構數組共享內存

[英]Shared memory with array of structs

我正在使用結構數組在兩個進程之間共享數據。 當我嘗試將共享內存訪問到父進程中時,該程序在3秒鍾后引發了Segmentation fault錯誤。 為什么數據沒有正確共享?

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

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define LEN     3

typedef struct {
    int val;
} val_t;

int
main (int argc, char *argv[])
{
    key_t   key;
    int     shmid, i, size;
    val_t   **val;

    if ((key = ftok(argv[0], 'D')) == -1) {
        perror("ftok");
        exit(1);
    }

    size = sizeof(val_t *) * LEN;

    if (fork() == 0) {
        if ((shmid = shmget(key, size, IPC_CREAT | IPC_EXCL | 0666)) == -1) {
            perror("shmget");
            exit(1);
        }

        val = (val_t **) shmat(shmid, 0, 0);
        if (val == (val_t **)(-1)) {
            perror("shmat");
            exit(1);
        }

        for (i = 0; i < LEN; i++) {
            val[i] = (val_t *) malloc(sizeof(val_t));
            val[i]->val = i;
        }

        while (val[0]->val != 3)
            sleep(1);

        if (shmdt(val) == -1) {
            perror("shmdt");
            exit(1);
        }
        shmctl(shmid, IPC_RMID, NULL);
    }
    else {
        sleep(3);

         if ((shmid = shmget(key, size, IPC_EXCL)) == -1) {
            perror("shmget");
            exit(1);
        }

        val = (val_t **) shmat(shmid, 0, 0);
        if (val == (val_t **)(-1)) {
            perror("shmat");
            exit(1);
        }

        printf("%d\n", val[0]->val);
        val[0]->val = 3;

        if (shmdt(val) == -1) {
            perror("shmdt");
            exit(1);
        }
    }

    return 0;
}

問題是您沒有共享結構數組,而是共享了指向結構的指針數組,並且這些指針指向使用malloc分配的非共享內存。 您想要的代碼更像:

val_t   *val;
size = sizeof(val_t) * LEN;

if (fork() == 0) {
    if ((shmid = shmget(key, size, IPC_CREAT | IPC_EXCL | 0666)) == -1) {
        perror("shmget");
        exit(1); }

    val = (val_t *) shmat(shmid, 0, 0);
    if (val == (val_t *)(-1)) {
        perror("shmat");
        exit(1); }

    for (i = 0; i < LEN; i++) {
        val[i].val = i; }

也就是說,使用結構體數組,而不是結構體指針數組。

請注意,這僅在您的結構(因此您的共享內存)中永遠沒有任何指針的情況下才起作用-即使這些指針指向共享內存,它也可能位於不同進程中的不同地址。

您想在進程之間共享struct ,但是您只共享指向結構的指針 如果那些指向在派生之前分配和初始化的struct的對象,則它們在兩個進程中均有效,但是指向struct的不同副本( malloc()僅分配私有內存,從不共享)。 但是,實際上,指針僅在執行malloc()的子代中有效。

因此,分配一個結構數組,而不是一個指針數組:

val_t *val;

/* ... */

size = sizeof(val_t) * LEN;

/* ... */

val = (val_t *) shmat(shmid, 0, 0);

而且,如果您這樣做,就不需要malloc() (或free() )單個struct

在,

val = (val_t **) shmat(shmid, 0, 0);

val指向共享內存中類型為val_t*的數組。 可以在附加到同一共享內存段的另一個進程中訪問它。

但在,

val[i] = (val_t *) malloc(sizeof(val_t));

val[i]指向由malloc()分配的malloc() ,該內存是進程專用的。 不能在其他進程中訪問此指針。 因此,當您在子進程中執行此操作時,就會出現Segmentation fault

val[0]->val = 3;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM