对共享内存 C 中的元素进行操作时出错

问题描述 投票:0回答:1

我编写了将结构插入共享内存的代码。我进行了调试打印,试图找出进程停止的位置以及出现错误的原因。显然,通过对共享内存中的元素进行操作,它会出错,但我不明白为什么。我该如何解决?

static shared_pid_data *shared_pid_atom;

static int shmidA;
static int semidA;

void atomSharedPidInit(){
    key_t key = ftok("shmfileA",65);
    printf("atomSharedPidInit - key = ftok\n");
    shmidA = shmget(key, sizeof(shared_pid_data), 0666|IPC_CREAT);
    printf("atomSharedPidInit - shmget\n");
    shared_pid_atom = (shared_pid_data*) shmat(shmidA, (void*)0, 0);
    printf("atomSharedPidInit - shmat\n");
    key_t sem_key = ftok("semfileA", 75);
    printf("atomSharedPidInit - sem_key = ftok\n");
    semidA = semget(sem_key, 1, 0666 | IPC_CREAT);
    printf("atomSharedPidInit - semget\n");
    semctl(semidA, 0, SETVAL, 1);
    printf("atomSharedPidInit - semctl\n");
}

void lockA() {
    struct sembuf sba = {(unsigned short) 0, -1, 0};
    semop(semidA, &sba, 1);
}

void unlockA() {
    struct sembuf sba = {(unsigned short) 0, 1, 0};
    semop(semidA, &sba, 1);
}

void atomSharedPidWrite(pid_t pid) {
    lockA();
    printf("atomSharedPidWrite - lock\n");
    int dim = shared_pid_atom->dimensione;
    printf("atomSharedPidWrite - int dim\n");
    if (dim < 1000) {
        printf("atomSharedPidWrite - if\n");
        shared_pid_atom->atomi_pid[shared_pid_atom->dimensione] = pid;
        shared_pid_atom->dimensione++;
        printf("pid : %d  dimensione : %d ",shared_pid_atom->atomi_pid[shared_pid_atom->dimensione-1],shared_pid_atom->dimensione);
    } else {
        fprintf(stderr, "Shared memory is full\n");
    }
    unlockA();
}

int main (){
    atomSharedPidInit();
    printf("simulazione - atomSharedPidInit\n");
    alarm((unsigned int)sim_duration);
    printf("simulazione - alarm\n");
    print_statistics();

    for (int i = 0; i < n_atomi_init; i++) {
        atomoPID = fork();
        if (atomoPID == 0) {
            printf("Atomo - fork\n");
            srand((unsigned int)(time(NULL) + getpid()));
            printf("Atomo - srand\n");
            atomSharedPidWrite(getpid());
            printf("Atomo - atomSharedPidWrite(getpid())\n");
            
            int numero_atomico = rand() % max_num_atomico + min_num_atomico;
            printf("%d %d %d ", numero_atomico, max_num_atomico, min_num_atomico);
            char num_atomico_str[10];
            sprintf(num_atomico_str, "%d", numero_atomico);
            execl("./atomo", "./atomo", num_atomico_str, NULL);
            exit(0);
        } else if (atomoPID < -1) {
            kill(getpid(), SIGINT);
            exit(EXIT_FAILURE);
        }
    }
}

这就是我通过启动该过程得到的结果:

atomSharedPidInit - key = ftok
atomSharedPidInit - shmget
atomSharedPidInit - shmat
atomSharedPidInit - sem_key = ftok
atomSharedPidInit - semget
atomSharedPidInit - semctl
simulazione - atomSharedPidInit
simulazione - alarm
Current state:
Total energy: 0
Total energy consumed: 0
Total energy available: 0
Total atomi attivi: 0
Total scissions: 0
Total activations: 0
Total scorie: 0
+---------------------------------------------------+
Atomo - fork
Atomo - srand
atomSharedPidWrite - lock
Atomo - fork
Atomo - srand
Atomo - fork
Atomo - srand
Atomo - fork
Atomo - fork
Atomo - srand
Atomo - srand
atomSharedPidWrite - lock
atomSharedPidWrite - lock
atomSharedPidWrite - lock
atomSharedPidWrite - lock
make: *** [Makefile:38: run] Errore di segmentazione (creato dump del core)

即使我在共享内存上执行像

shared_pid_atom->dimensione = 0;
这样非常平庸的操作,它也无法完成。我不明白为什么。

c struct shared-memory
1个回答
0
投票

建议您检查一下

shmidA
semidA
的返回值是否有效:可能是您没有访问共享内存的权限。 看来你的孩子进程在

之前就已经死亡了
int dim = shared_pid_atom->dimensione;

已执行,因此指针

shared_pid_atom
可能无效。

此外,你的锁不起作用:

  • 你必须先等待 sem 0,然后你才能写入值 1
  • 相反,在您的代码中,您正在编写 1 而无需等待 0,因此所有进程都会像您在日志中看到的那样同时进入
  • 参见例如sem op 使用示例
© www.soinside.com 2019 - 2024. All rights reserved.