信号优雅关闭
Signal Graceful Shutdown
题目详情
高频交易系统需要稳健的生命周期管理,防止在异常终止时出现数据损坏或未定义状态。信号处理允许应用程序拦截终止请求并执行优雅关闭序列,确保订单终结和资源安全释放后再退出进程。
任务:实现 GracefulShutdown 类,注册 SIGTERM 和 SIGINT 信号处理器,在收到信号后触发有序关闭:停止接收新订单、等待现有订单处理完成、释放资源后退出。
英文原题
High-frequency trading systems require robust lifecycle management to prevent data corruption or undefined states during abrupt termination. Signal handling allows applications to intercept termination requests and execute a graceful shutdown sequence, ensuring orders are finalized and resources are released safely before the process exits.
Task
Implement the GracefulShutdown class to manage application lifecycle events via POSIX signal handling. The class must register a handler for SIGTERM th
解析
问题分析
交易系统必须在收到 SIGTERM/SIGINT 时优雅关闭:停止接收新订单、完成在途订单处理、刷新日志和状态后退出。使用 signalfd 将信号集成到事件循环。
实现
class GracefulShutdown {
sigset_t mask_; int fd_;
std::atomic<bool> stopping_{false};
public:
GracefulShutdown() {
sigemptyset(&mask_); sigaddset(&mask_, SIGTERM); sigaddset(&mask_, SIGINT);
sigprocmask(SIG_BLOCK, &mask_, nullptr); // 阻塞信号(避免默认终止)
fd_ = ::signalfd(-1, &mask_, SFD_NONBLOCK);
}
bool shouldStop() { return stopping_.load(std::memory_order_acquire); }
void poll() {
signalfd_siginfo info;
if (::read(fd_, &info, sizeof(info)) > 0) stopping_ = true;
}
int fd() const { return fd_; }
};复杂度与边界
- 时间复杂度:poll O(1)
- 空间复杂度:O(1)
- 边界条件:(1) 必须在任何线程启动前阻塞信号 (2) SIGKILL 不可捕获 (3) 关闭超时后需强制退出
英文解析
Analysis
Trading systems must shut down gracefully on SIGTERM/SIGINT: stop accepting new orders, complete in-flight order processing, flush logs and state, then exit. signalfd integrates signals into the event loop.
Solution
class GracefulShutdown {
sigset_t mask_; int fd_;
std::atomic<bool> stopping_{false};
public:
GracefulShutdown() {
sigemptyset(&mask_); sigaddset(&mask_, SIGTERM); sigaddset(&mask_, SIGINT);
sigprocmask(SIG_BLOCK, &mask_, nullptr); // Block signals (prevent default termination)
fd_ = ::signalfd(-1, &mask_, SFD_NONBLOCK);
}
bool shouldStop() { return stopping_.load(std::memory_order_acquire); }
void poll() {
signalfd_siginfo info;
if (::read(fd_, &info, sizeof(info)) > 0) stopping_ = true;
}
int fd() const { return fd_; }
};Complexity & Edge Cases
- Time complexity: poll O(1)
- Space complexity: O(1)
- Edge cases: (1) Must block signals before any thread starts (2) SIGKILL cannot be caught (3) Forced exit needed after shutdown timeout
Verification
Send SIGTERM to process, verify shouldStop() becomes true. Test graceful shutdown sequence: stop orders, flush logs, exit. Confirm SIGKILL terminates immediately.
Key Considerations
signalfd converts signal handling from asynchronous interrupts to synchronous event-loop processing. In trading systems, this means the shutdown sequence runs in the main event loop thread - no race conditions between signal handlers and normal processing. A shutdown timeout (e.g., 5 seconds) ensures the process exits even if in-flight orders cannot complete.