Linux用户态如何运行无抢占代码?线程中是否可用用户态原子函数?
Let's break down your two questions one by one, since they touch on different aspects of user-space execution and concurrency in Linux:
1. How to run user-space code without preemption on Linux?
First off, let's clarify: by default, all user-space processes/threads in Linux are preemptible—the kernel's scheduler can yank the CPU away from your code at any time to run other tasks. But if you need a section of code to run without being preempted by other user-space tasks, here's the standard approach:
Use a real-time scheduling policy
Linux offers two real-time scheduling classes:SCHED_FIFO: A first-in-first-out policy. Once your thread gets the CPU, it will keep running until it voluntarily gives up the CPU (e.g., via a blocking system call) or a higher-priority real-time thread becomes ready.SCHED_RR: Round-robin real-time scheduling. Similar toSCHED_FIFO, but each thread gets a time slice—once the slice expires, the scheduler switches to the next thread of the same priority.
Set a high enough real-time priority
Real-time priorities range from 1 (lowest) to 99 (highest). You'll need to set a priority high enough to ensure no other real-time thread can preempt yours.Required permissions
To set real-time scheduling policies, your process needs theCAP_SYS_NICEcapability. You can either run the program withsudo, or grant the capability permanently usingsetcap cap_sys_nice=ep ./your-program.
Here's a quick C code example to set up a non-preemptible (by user-space tasks) thread:
#include <sched.h> #include <stdio.h> #include <stdlib.h> int main() { struct sched_param param; int max_prio = sched_get_priority_max(SCHED_FIFO); if (max_prio == -1) { perror("Failed to get max real-time priority"); exit(EXIT_FAILURE); } param.sched_priority = max_prio; if (sched_setscheduler(0, SCHED_FIFO, ¶m) == -1) { perror("Failed to set SCHED_FIFO policy"); fprintf(stderr, "Tip: Run with sudo or set CAP_SYS_NICE capability\n"); exit(EXIT_FAILURE); } // Your code that shouldn't be preempted goes here // Note: Hardware interrupts will still pause execution temporarily, // but the kernel will resume your thread immediately after the interrupt. // Avoid blocking system calls (like sleep(), read() from a slow fd) here—they'll yield the CPU. return 0; }
2. Are there usable atomic functions in user-space for code running in a thread (marked with thread-stop-preemption //code to run thread-start-preemption)?
Absolutely—user-space has robust atomic operation support, powered by CPU-level atomic instructions (e.g., lock prefix on x86) and compiler built-ins/standard libraries. These are designed to safely modify shared variables across threads without race conditions.
Common options for user-space atomic operations:
C11 Standard
<stdatomic.h>(recommended for modern code):
This is the standardized, portable way to handle atomic operations. It defines atomic types (likeatomic_int,atomic_bool) and functions to manipulate them atomically, such asatomic_load(),atomic_store(),atomic_fetch_add(), andatomic_compare_exchange_strong().Example usage:
#include <stdatomic.h> #include <pthread.h> #include <stdio.h> atomic_int shared_counter = ATOMIC_VAR_INIT(0); void* thread_work(void* arg) { // thread-stop-preemption for (int i = 0; i < 10000; i++) { // Atomically increment the counter by 1 atomic_fetch_add(&shared_counter, 1); } // thread-start-preemption return NULL; } int main() { pthread_t t1, t2; pthread_create(&t1, NULL, thread_work, NULL); pthread_create(&t2, NULL, thread_work, NULL); pthread_join(t1, NULL); pthread_join(t2, NULL); printf("Final counter value: %d\n", atomic_load(&shared_counter)); return 0; }GCC/Clang built-in functions (for older codebases):
If you can't use C11, compilers like GCC provide built-ins like__sync_fetch_and_add()and__sync_bool_compare_and_swap()that work similarly to the C11 atomic functions.
Important note:
Atomic functions only guarantee that a single memory operation is atomic—they don't make your entire //code to run block non-preemptible. If you need the entire code block to run without being interrupted by other threads, you'll need to combine atomic operations with either:
- The real-time scheduling approach from question 1, or
- A mutex (like
pthread_mutex_t) to lock the critical section.
内容的提问来源于stack exchange,提问作者Vineet

