面试题答案
一键面试架构设计
- 信号处理调度器:负责接收信号,根据信号类型和依赖关系,调度相应的信号处理函数。
- 信号处理函数注册机制:允许子模块注册其信号处理函数以及依赖关系。
- 状态管理:用于保存信号处理过程中的状态,以便后续信号处理函数依赖使用。
关键数据结构
// 定义信号处理函数类型
typedef void (*SignalHandler)(int);
// 定义信号依赖关系结构体
typedef struct {
int signal;
int dependsOnSignal;
} SignalDependency;
// 定义信号处理描述结构体
typedef struct {
int signal;
SignalHandler handler;
SignalDependency dependency;
} SignalHandlerDescriptor;
关键函数
- 注册信号处理函数
void registerSignalHandler(int signal, SignalHandler handler, int dependsOnSignal) {
SignalHandlerDescriptor descriptor;
descriptor.signal = signal;
descriptor.handler = handler;
descriptor.dependency.signal = signal;
descriptor.dependency.dependsOnSignal = dependsOnSignal;
// 这里假设将descriptor添加到一个全局数组或链表中进行管理
// 例如,定义一个全局数组SignalHandlerDescriptor handlers[MAX_SIGNALS];
// 并通过一个全局变量int handlerCount = 0;记录已注册的数量
handlers[handlerCount++] = descriptor;
}
- 信号处理调度函数
void signalDispatcher(int signum) {
for (int i = 0; i < handlerCount; i++) {
if (handlers[i].signal == signum) {
// 检查依赖关系
if (handlers[i].dependency.dependsOnSignal == 0 ||
/* 假设存在一个函数isSignalHandled检查依赖信号是否已处理 */
isSignalHandled(handlers[i].dependency.dependsOnSignal)) {
handlers[i].handler(signum);
// 标记该信号已处理
markSignalHandled(signum);
}
}
}
}
- 安装信号处理函数
void installSignalHandlers() {
struct sigaction sa;
sa.sa_handler = signalDispatcher;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
for (int i = 0; i < handlerCount; i++) {
sigaction(handlers[i].signal, &sa, NULL);
}
}
示例使用
// 示例信号处理函数
void handleSIGUSR1(int signum) {
// 处理逻辑
}
void handleSIGALRM(int signum) {
// 处理逻辑并设置状态
}
int main() {
registerSignalHandler(SIGALRM, handleSIGALRM, 0);
registerSignalHandler(SIGUSR1, handleSIGUSR1, SIGALRM);
installSignalHandlers();
while (1) {
// 主循环,等待信号
pause();
}
return 0;
}
上述框架通过注册机制管理信号处理函数及其依赖关系,调度器根据依赖关系决定是否执行信号处理函数,并且提供了安装信号处理函数的方法,方便子模块扩展新的信号处理逻辑。