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

为何修改pthread_getattr_default_np返回的pthread_attr_t会影响全局默认属性?

Linux下pthread_getattr_default_np与pthread_attr_setaffinity_np的意外行为问题

在Linux环境下使用pthread_getattr_default_np()和pthread_attr_setaffinity_np()时遇到不符合预期的行为:

  • 通过pthread_setattr_default_np()设置了基于当前线程CPU亲和性的全局默认线程属性
  • 调用pthread_getattr_default_np()将默认属性存入变量attr1,随后修改attr1的CPU亲和性为仅CPU3
  • 预期仅attr1会受影响,但再次调用pthread_getattr_default_np()得到的attr2也被设置为仅CPU3,全局默认属性被意外修改

示例代码

#include <pthread.h>
#include <stdio.h>

void display_pthread_attr(pthread_attr_t* attr, const char* label) 
{
    cpu_set_t cpuset;
    int ret = pthread_attr_getaffinity_np(attr, sizeof(cpu_set_t), &cpuset);
    if (ret != 0) 
    {
        printf("%s: Failed to get CPU affinity (error %d)\n", label, ret);
        return;
    }

    printf("%s CPU SET: ", label);
    for (int i = 0; i < CPU_SETSIZE; ++i) 
    {
        if (CPU_ISSET(i, &cpuset)) 
        {
            printf("%d ", i);
        }
    }
    printf("\n");
}

void overrideDefaultThreadAttribute() {
    pthread_attr_t* attribute = new pthread_attr_t;
    pthread_attr_init(attribute);

    cpu_set_t cpuSet;
    pthread_getaffinity_np(pthread_self(), sizeof(cpuSet), &cpuSet);
    pthread_attr_setaffinity_np(attribute, sizeof(cpu_set_t), &cpuSet);

    pthread_setattr_default_np(attribute);

    display_pthread_attr(attribute, "OverrideDefaultThreadAttribute");
}

int main() {
    overrideDefaultThreadAttribute();

    pthread_attr_t attr1, attr2;

    pthread_getattr_default_np(&attr1);
    display_pthread_attr(&attr1, "Default attr1"); 

    // Modify attr1
    cpu_set_t cpus;
    CPU_ZERO(&cpus);
    CPU_SET(3, &cpus);
    pthread_attr_setaffinity_np(&attr1, sizeof(cpu_set_t), &cpus);
    display_pthread_attr(&attr1, "attr1 pinned to 3");

    // Get another default attribute
    pthread_getattr_default_np(&attr2);
    display_pthread_attr(&attr2, "Default attr2");
}

输出结果

OverrideDefaultThreadAttribute CPU SET: 0 1 2 3 4 5 6 18 19 20 21 22 23 24 
Default attr1 CPU SET: 0 1 2 3 4 5 6 18 19 20 21 22 23 24 
attr1 pinned to 3 CPU SET: 3
Default attr2 CPU SET: 3

问题原因

pthread_getattr_default_np()返回的是指向全局默认属性对象的直接引用,而非独立副本。当你修改通过该函数获取到的pthread_attr_t变量时,实际上是直接操作全局默认属性的内存区域,因此修改会同步影响后续获取的默认属性。

解决方案

若要修改默认属性的副本而不影响全局设置,需先初始化新的属性对象,再通过pthread_attr_copy()复制默认属性到新对象,之后对副本进行修改:

// 正确用法示例
pthread_attr_t attr_copy;
pthread_attr_init(&attr_copy); // 初始化新属性对象

pthread_attr_t default_attr;
pthread_getattr_default_np(&default_attr);
pthread_attr_copy(&attr_copy, &default_attr); // 复制默认属性到副本

// 修改副本,不会影响全局默认属性
cpu_set_t cpus;
CPU_ZERO(&cpus);
CPU_SET(3, &cpus);
pthread_attr_setaffinity_np(&attr_copy, sizeof(cpu_set_t), &cpus);

另外,原代码中overrideDefaultThreadAttribute()函数动态分配pthread_attr_t后未调用pthread_attr_destroy()释放资源,会导致内存泄漏,需补充释放逻辑:

void overrideDefaultThreadAttribute() {
    pthread_attr_t* attribute = new pthread_attr_t;
    pthread_attr_init(attribute);

    // ... 原有逻辑 ...

    pthread_attr_destroy(attribute); // 销毁属性对象
    delete attribute; // 释放动态分配的内存
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 20:27:40