面试题答案
一键面试可能遇到的错误
- 无效的信号量标识符:传递给初始化函数的信号量标识符可能是无效的,例如未正确创建或已被销毁。
- 权限问题:进程可能没有足够的权限来初始化信号量,比如在某些系统中,需要特定的用户权限(如root权限)来操作信号量。
- 资源不足:系统的信号量资源可能已耗尽,无法再创建新的信号量或对其进行初始化。
检测并处理错误的代码示例
#include <stdio.h>
#include <stdlib.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <sys/types.h>
// 联合体用于semctl调用
union semun {
int val; /* 用于SETVAL */
struct semid_ds *buf; /* 用于IPC_STAT, IPC_SET */
unsigned short *array; /* 用于GETALL, SETALL */
struct seminfo *__buf; /* 用于IPC_INFO (Linux-specific) */
};
int main() {
key_t key;
int semid;
// 生成一个唯一的键值
key = ftok(".", 'a');
if (key == -1) {
perror("ftok");
return 1;
}
// 创建信号量集
semid = semget(key, 1, IPC_CREAT | 0666);
if (semid == -1) {
perror("semget");
return 1;
}
union semun arg;
arg.val = 1; // 初始化信号量值为1
// 初始化信号量
if (semctl(semid, 0, SETVAL, arg) == -1) {
perror("semctl SETVAL");
// 清理创建的信号量集
if (semctl(semid, 0, IPC_RMID) == -1) {
perror("semctl IPC_RMID");
}
return 1;
}
printf("信号量初始化成功\n");
// 这里可以进行其他使用信号量的操作
// 程序结束时清理信号量集
if (semctl(semid, 0, IPC_RMID) == -1) {
perror("semctl IPC_RMID");
return 1;
}
return 0;
}
在上述代码中:
- ftok函数:用于生成一个唯一的键值,如果失败,
perror
函数会打印错误信息。 - semget函数:用于创建信号量集,如果失败,同样使用
perror
打印错误信息。 - semctl函数:用于初始化信号量(SETVAL操作),如果初始化失败,首先打印错误信息,然后尝试删除刚创建的信号量集(IPC_RMID操作)以清理资源。如果删除信号量集也失败,同样打印错误信息。成功初始化后,程序会打印“信号量初始化成功”。程序结束时,再次使用
semctl
删除信号量集。