You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 to SCHED_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 the CAP_SYS_NICE capability. You can either run the program with sudo, or grant the capability permanently using setcap 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, &param) == -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 (like atomic_int, atomic_bool) and functions to manipulate them atomically, such as atomic_load(), atomic_store(), atomic_fetch_add(), and atomic_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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:31:45