操作系统课程疑问:为何pause()属于CPU高效利用方式?
pause() Does Under the Hood Hey there! As someone who's just starting out with OS concepts and C, this is such a smart question—understanding how pause() works is key to writing efficient signal-handling code, and it's way better than that busy-wait loop you were using before. Let's break down exactly what happens when you call this system call:
First, Let's Recap the Problem with Your Original Loop
That while (!done) loop you had? It's what's called a busy wait. Your process is constantly hogging CPU time, repeatedly checking the done variable even when there's nothing to do. The CPU can't do anything else useful with that time, which is why your resource usage was sky-high. pause() fixes this entirely.
What Happens When You Call pause()?
Here's the step-by-step play-by-play:
Step 1: Tell the OS to put your process to sleep
As soon as your code hitspause(), your process sends a request to the kernel: "I don't need to run until a signal arrives. Put me on hold." The kernel then moves your process from the running/ready queue (the list of processes waiting for CPU time) to a waiting/sleep queue. At this point, your process stops executing entirely—it doesn't get any CPU time slices, so your CPU utilization drops to 0% for this process. Perfect, no wasted resources!Step 2: Wait for a signal
Your process stays in this dormant state until one of two things happens:- A signal is sent to it (like
SIGINTfrom Ctrl+C, or a signal from thekillcommand). - A signal that terminates the process is received (like
SIGKILL, which can't be caught).
- A signal is sent to it (like
Step 3: Wake up and resume execution
When a non-terminating signal arrives, the kernel first handles the signal: if you registered a custom signal handler (like a function to setdone = 1), that handler runs first. Once the signal is handled, the kernel moves your process back to the ready queue. When it gets its turn on the CPU,pause()returns-1, and theerrnovariable is set toEINTR(meaning the system call was interrupted by a signal). Your code then picks up right where it left off after thepause()call.
A Quick Example to See It in Action
Here's a simple snippet that uses pause() properly with a signal handler:
#include <signal.h> #include <stdio.h> #include <unistd.h> #include <errno.h> #include <stdlib.h> volatile sig_atomic_t done = 0; // Signal handler for SIGINT (Ctrl+C) void handle_sigint(int sig) { done = 1; printf("\nReceived Ctrl+C! Preparing to exit...\n"); } int main() { // Register our custom handler for SIGINT if (signal(SIGINT, handle_sigint) == SIG_ERR) { perror("Failed to set signal handler"); exit(EXIT_FAILURE); } printf("Press Ctrl+C to exit...\n"); while (!done) { pause(); // Sleep until a signal wakes us up if (errno == EINTR) { // This means pause() was interrupted by a signal—exactly what we want! continue; } } printf("Exiting successfully!\n"); return EXIT_SUCCESS; }
In this code, the process sleeps peacefully via pause() until you hit Ctrl+C. The signal handler sets done to 1, pause() returns, and the loop exits cleanly—no CPU wasted in the meantime.
内容的提问来源于stack exchange,提问作者Meltdown

