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

创建8个绑定核心的线程后,为何出现更高编号的线程?

线程绑定后出现未预期线程编号的问题

我在32核Intel云实例上运行程序,希望仅使用8个线程,通过以下C代码创建并绑定线程:

#define _GNU_SOURCE
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

extern void * Complex_Calc_YZ_fn();

int thread_create_in_C(int numberOfProcessors) {

    pthread_t threads[numberOfProcessors];

    pthread_attr_t attr;
    cpu_set_t cpus;
    pthread_attr_init(&attr);

    for (int i = 0; i < numberOfProcessors; i++) {
       CPU_ZERO(&cpus);
       CPU_SET(i, &cpus);
       printf("Core created %d\n", i);
       pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &cpus);
       pthread_create(&threads[i], &attr, Complex_Calc_YZ_fn, NULL);
    }

    for (int i = 0; i < numberOfProcessors; i++) {
        pthread_join(threads[i], NULL);
        printf("Core joined %d\n", i);
    }

    return numberOfProcessors;
}

这段代码被链接到一个更大的程序中,且是程序中唯一创建和调度线程的逻辑。输出显示确实创建了8个线程,每个线程都通过pthread_attr_setaffinity_np绑定到对应核心。但在调试时,断点触发时却看到“thread 9”或“thread 10”的标识,而我只创建了编号0-7的8个线程。

我有两个问题:

  1. 当处理器有更多可用核心时,绑定到核心的线程编号是否会迁移?比如thread6会不会变成thread10?如果会,如何避免?
  2. 如果不会,还有哪些原因能解释这个现象?

问题解答

1. 绑定核心的线程编号是否会迁移?

不会。线程的pthread_t标识是进程内的唯一标识符,和CPU核心绑定逻辑完全无关。pthread_attr_setaffinity_np只是限制线程可以运行的CPU核心集合,并不会修改线程本身的ID,也不会导致线程编号“迁移”。你创建的线程ID会一直保持创建时的数值,不会因为CPU资源情况变化而改变。

2. 出现未预期线程编号的可能原因

  • 主线程被计入总数:你创建的8个线程是额外线程,加上程序启动时就存在的主线程,进程内总共至少有9个线程。调试器显示的“thread 9”很可能就是主线程。
  • 依赖库创建了后台线程:很多基础库或第三方组件会在后台隐性创建线程,比如:
    • C标准库的内存分配器(如glibc的malloc)可能会创建后台线程用于内存管理;
    • 日志、监控、信号处理组件;
    • 动态链接库初始化时启动的线程;
      这些线程不在你的代码控制范围内,但会被调试器检测到。
  • 调试器的编号规则差异:调试器显示的“thread N”编号通常是调试器自身按线程发现顺序分配的序号,和线程实际的pthread_t数值没有对应关系。比如主线程可能被编号为1,你创建的8个线程是2-9,若有额外后台线程就会被编为10及以上。
  • 隐性线程创建逻辑:即使你认为自己的代码是唯一创建线程的地方,也可能存在遗漏——比如程序中其他模块调用了pthread_create、fork(虽然fork是进程,但也可能关联线程),或者使用了线程池等组件,这些都可能产生额外线程。

内容的提问来源于stack exchange,提问作者RTC222

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 13:32:49