shmat()失败并删除“Identifier”

时间:2014-02-28 20:10:38

标签: c shared-memory identifier

我正在尝试学习如何使用信号量,并且我从here获取了以下代码,并添加了here

的一些内容
 /*
 ** semdemo.c -- demonstrates semaphore use as a file locking mechanism
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include "parameter.h"

#define MAX_RETRIES 10

union semun {
    int val;
    struct semid_ds *buf;
    ushort *array;
};

/*
 ** initsem() -- more-than-inspired by W. Richard Stevens' UNIX Network
 ** Programming 2nd edition, volume 2, lockvsem.c, page 295.
 */
char *shm;

int initsem(key_t key, int nsems) /* key from ftok() */ {
    int i;
    union semun arg;
    struct semid_ds buf;
    struct sembuf sb;
    int semid;

semid = semget(key, nsems, IPC_CREAT | IPC_EXCL | 0666);

if (semid >= 0) { /* we got it first */
    sb.sem_op = 1;
    sb.sem_flg = 0;
    arg.val = 1;

    printf("press return\n");
    getchar();

    for (sb.sem_num = 0; sb.sem_num < nsems; sb.sem_num++) {
        /* do a semop() to "free" the semaphores. */
        /* this sets the sem_otime field, as needed below. */
        if (semop(semid, &sb, 1) == -1) {
            int e = errno;
            semctl(semid, 0, IPC_RMID); /* clean up */
            errno = e;
            return -1; /* error, check errno */
        }
    }
    if ((shm = (char*) shmat(semid, NULL, 0)) == (char *) -1) {
        perror("shmat");
        exit(1);
    }
} else if (errno == EEXIST) { /* someone else got it first */
    int ready = 0;

    semid = semget(key, nsems, 0); /* get the id */
    if (semid < 0) return semid; /* error, check errno */

    /* wait for other process to initialize the semaphore: */
    arg.buf = &buf;
    for (i = 0; i < MAX_RETRIES && !ready; i++) {
        semctl(semid, nsems - 1, IPC_STAT, arg);
        if (arg.buf->sem_otime != 0) {
            ready = 1;
        } else {
            sleep(1);
        }
    }
    if (!ready) {
        errno = ETIME;
        return -1;
    }
    if ((shm = shmat(semid, NULL, 0)) < 0) {
        perror("shmat");
        exit(1);
    }
} else {
    return semid; /* error, check errno */
}

return semid;
}

int main(void) {
key_t key;
int semid;
struct sembuf sb;

sb.sem_num = 0;
sb.sem_op = -1; /* set to allocate resource */
sb.sem_flg = SEM_UNDO;

key = KEY;

/* grab the semaphore set created by seminit.c: */
if ((semid = initsem(key, 1)) == -1) {
    perror("initsem");
    exit(1);
}

printf("Press return to lock: ");
getchar();
printf("Trying to lock...\n");

if (semop(semid, &sb, 1) == -1) {
    perror("semop");
    exit(1);
}

printf("Locked.\n");
printf("Press return to unlock: ");
getchar();

sb.sem_op = 1; /* free resource */
if (semop(semid, &sb, 1) == -1) {
    perror("semop");
    exit(1);
}

printf("Unlocked\n");

return 0;
}

parameter.h

#ifndef PARAMETER_H
#define PARAMETER_H

#define KEY 91234567
#define SHM_SIZE 1024

#endif  /* PARAMETER_H */

当我尝试使用shmat时,我收到“Identifier removed”错误。我究竟做错了什么?我该如何解决呢?请帮忙。

1 个答案:

答案 0 :(得分:1)

此次电话

if (-1 == semctl(semid, 0, IPC_RMID)) /* clean up */

删除信号量标识符,因此可以预期以下对shmat()的调用给出的错误。


似乎缺少代码
#include <sys/shm.h>

最后这个电话

if ((shm = shmat(semid, NULL, 0)) < 0) {

应该是

if ((shm = shmat(semid, NULL, 0)) == (char*) -1) {