我正在尝试学习如何使用信号量,下面的代码取自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;
}
参数.h
#ifndef PARAMETER_H
#define PARAMETER_H
#define KEY 91234567
#define SHM_SIZE 1024
#endif /* PARAMETER_H */
当我尝试使用shmat时,我得到了“Identifier removed”错误。我做错什么了?我怎么能修好它。请帮忙。
最佳答案
这个电话
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) {
关于c - shmat()失败,并显示“标识符已删除”,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22104894/