printf("Entering sigsuspend loop. Waiting for SIGUSR1...\n");
//3. 主循环:等待信号 while (!sigusr1_flag) { printf(" Calling sigsuspend()... (temporarily unblocking SIGUSR1)\n"); // sigsuspend 会: // a. 临时将进程的信号掩码设置为 suspend_wait_mask (这里是空集,即不额外阻塞) // 结合上一步,这意味着 SIGUSR1 现在是 unblocked。 // b. 挂起进程。 // c. 如果收到 SIGUSR1: // i. 内核调用 handle_sigusr1。 // ii. handle_sigusr1 执行完毕。 // iii.sigsuspend 返回 -1, errno=EINTR。 // d. 恢复 sigprocmask 调用前的掩码 (orig_mask,即阻塞 SIGUSR1)。 int result = sigsuspend(&suspend_wait_mask);
// 因为 sigsuspend 只有被信号中断才会返回,所以检查 errno 是标准做法 if (result == -1 && errno == EINTR) { printf(" sigsuspend() returned (interrupted by signal).\n"); // 检查是哪个信号触发的(通过全局标志) if (sigusr1_flag) { printf(" Confirmed: SIGUSR1 was received and handled.\n"); } else { printf(" Interrupted by a different signal (e.g., SIGINT?).\n"); // 如果是 SIGINT 或 SIGTERM,程序通常应该退出 // 但因为我们没有在 sigsuspend mask 中明确阻塞它们, // 它们也可能唤醒 sigsuspend。 // 为了精确等待 SIGUSR1,我们应该在 suspend_wait_mask 中阻塞它们。 // 让我们再修正一次。 break; // 简单地退出循环 } } else { // 这不太可能发生,除非有其他严重错误 perror("sigsuspend"); break; } }
//4. 循环结束,说明收到了 SIGUSR1 或者被其他信号中断 if (sigusr1_flag) { printf("\nMain loop exited because SIGUSR1 was received.\n"); } else { printf("\nMain loop exited because of another signal (e.g., SIGINT).\n"); }
printf("Entering loop to wait for SIGUSR1 using sigsuspend...\n"); while (!usr1_flag) { printf(" About to call sigsuspend()... waiting for SIGUSR1.\n"); // sigsuspend 会: // 1. 临时将掩码设置为 wait_for_sigusr1_mask (只阻塞 SIGINT)。 // 2. 挂起进程。 // 3. 如果收到 SIGUSR1 (未被阻塞),handle_usr1 被调用,然后 sigsuspend 返回 -1 (EINTR)。 // 4. 如果收到 SIGINT (被阻塞),行为取决于系统和信号是否排队,但通常会被延迟。 // 5. 返回后,掩码恢复为 orig_mask (即 block_sigusr1_and_sigint)。 int result = sigsuspend(&wait_for_sigusr1_mask);
if (result == -1 && errno == EINTR) { printf(" sigsuspend() returned (interrupted).\n"); if (usr1_flag) { printf(" -> It was SIGUSR1.\n"); } else { printf(" -> It was a different unblocked signal (unlikely in this setup) or SIGINT was delivered.\n"); // 在这个设置下,SIGINT 被阻塞,不太可能唤醒。但如果它以某种方式发生(例如,在设置掩码的间隙), // 程序的行为可能不符合预期。更健壮的方法是处理 SIGINT 在主循环条件中。 } } else { perror("sigsuspend"); break; // 错误退出 } }
if (usr1_flag) { printf("\nLoop exited successfully after receiving SIGUSR1.\n"); } else { printf("\nLoop exited, possibly due to an unexpected signal.\n"); }
printf("Restoring original signal mask (if needed, though sigsuspend should have done it).\n"); // sigsuspend 应该已经恢复了,但显式恢复是个好习惯 if (sigprocmask(SIG_SETMASK, &orig_mask, NULL) == -1) { perror("sigprocmask RESTORE"); }