c++ 线程绑定到cpu指定核心,独占CPU

本文介绍如何使用C语言通过线程绑定技术将线程固定到特定的CPU核心上执行,以减少线程间的通信开销并提高负载均衡。文中详细解释了使用sched_setaffinity等函数的具体步骤,并提供了示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

将线程绑定到cpu指定核心可以避免线程函数在多个核心上执行,从而减少线程间通信的开销,也方便查看负载,便于比较不同线程之间负载是否均衡。

cpu的声明(变量类型)cpu_set_t

绑定进程主要是通过三个函数,这三个函数都是在线程函数里面调用的

CPU_ZERO(&cpu_size_t)  cpu初始化,将这个cpu置为空

CPU_SET(int,cpu_size_t&)  int是cpu核的编号,这是一个设置具体哪个核的过程。专业名词叫亲和力,线程绑定核都是通过亲和力来完成的
sched_setaffinity(int,sizeof(cpu_set_t),&cpu_set_t)将线程与cpu核绑定,具体绑定哪个核通过上一步的CPU_SET已经确定int为0时表示此线程函数

#include <stdlib.h>
#include <stdio.h>
// #include <sys/types.h>
// #include <sys/sysinfo.h>
#include <unistd.h>

#define __USE_GUN
// #include <sched.h>
// #include <ctype.h>
#include <string.h>
#include <pthread.h>
#define THREAD_MAX_NUM 100// 1个cpu内最多进程数
int num=0; //cpu中核数

void* threadFun(void* arg)// arg传递线程标号,自己定义
{
    //sleep(2);
    cpu_set_t mask;// cpu核的集合
    cpu_set_t get;// 获取在集合中的cpu
    int* a=(int*)arg;
    printf("this is: %d\n",*a);// 打印这是第几个线程
    CPU_ZERO(&mask);// 将集合置为空集
    CPU_SET(*a,&mask);// 设置亲和力值
    
    if(sched_setaffinity(0,sizeof(cpu_set_t),&mask)==-1)// 设置线程cpu亲和力
    {
        printf("warning: could not set CPU affinity, continuing...\n");
    }
    while(1)
    {
        CPU_ZERO(&get);
        if(sched_getaffinity(0,sizeof(get),&get)==-1)// 获取线程cpu亲和力
        {
            printf("warning: could not get thread affinity, continuing...\n");
        }
        for(int i=0;i<num;++i)
        {
            if(CPU_ISSET(i,&get))// 判断线程与哪个cpu有亲和力
            {
                //printf("this thread %d is running processor: %d\n",i,i);
                int a=1000000*1000000;
            }
        }
    }
    return NULL;
}

int main(void)
{
    num=sysconf(_SC_NPROCESSORS_CONF);// 获取核数
    pthread_t thread[THREAD_MAX_NUM];
    printf("system has %i processor(s).\n",num);
    int tid[THREAD_MAX_NUM];
    for(int i=0;i<10;++i)
    {
        if(i%2==0)
        {
            tid[i]=i;// 每个线程必须有个tid[i]
            pthread_create(&thread[i],NULL,threadFun,(void*)&tid[i]);
        }
        //sleep(2);
    }
    for(int i=0;i<num;++i)
    {
        pthread_join(thread[i],NULL);
    }
    return 0;
}

注意线程库的选择,用c++自带的线程库是不可以的,这个库里的线程无法绑定到cpu核,必须使用<pthread.h>
num=sysconf(_SC_NPROCESSORS_CONF);是获取该计算机的cpu有多少核,在头文件<unistd.h>中定义
<pthread.h>中包含了<sched.h>所以不需要重复引用
CPU_SET这些函数都是通过宏来实现的,通过操作cpu_set_t的补码,我没有去仔细研究,参考这个:https://blog.youkuaiyun.com/STN_LCD/article/details/78134574
该程序的意思是0~9取偶数作为cpu核的id,将线程函数绑定在偶数核上
在CMakeLists.txt文件中要加上set(CMAKE_CXX_FLAGS “${CAMKE_CXX_FLAGS} -std=c++11 -pthread”)
结果如下
在这里插入图片描述
独占CPU核

上述设置只能保证进程或线程运行在特定的CPU上,仍然不能独自享有,时间片到了也是可能被切换出去的。通过配置Linux的启动参数grub,增加isolcpus=1,2,3来隔离指定的CPU核(从0开始)。

grub配置文件(/etc/default/grup)

在这里插入图片描述

注意:编辑grub文件后再执行该命令grub2-mkconfig -o /boot/grub2/grub.cfg更新grub

cmdline位置(/proc/cmdline)
root@analog:~# cat /proc/cmdline 

console=ttyPS0,115200 root=/dev/mmcblk0p2 rw earlycon rootfstype=ext4 rootwait cpuidle.off=1 isolcpus=0
root@analog:~#

转载出处:
c++ 线程绑定到cpu指定核心
Linux 用户态线程进程绑定CPU核

<think>好的,我现在需要回答用户关于“独占CPU是什么,怎样独占?”的问题。首先,我得理解用户的问题到底是什么。独占CPU应该是指让某个进程或线程完全占用一个或多个CPU核心,不让其他任务使用。接下来,我需要分步骤解释这个概念以及实现方法。 首先,定义部分。独占CPU通常指在操作系统中,某个进程或线程独享一个CPU核心,确保其他进程或线程不会被调度到该核心上运行。这有助于提高关键任务的性能和确定性,减少上下文切换带来的延迟。 然后是应用场景。用户可能想知道什么时候需要独占CPU,比如实时系统、高频交易、科学计算或者性能测试等需要高稳定性和低延迟的场景。 接下来是独占CPU的实现方法。这里需要分操作系统来讨论,因为Windows和Linux有不同的机制。 对于Linux系统,我记得有几种方法。第一种是使用isolcpus内核启动参数,将特定CPU核心隔离出来,不参与普通进程调度。然后通过taskset或cset将进程绑定到隔离的核心上。第二种是使用cgroups的cpuset子系统,限制进程只能在指定CPU核心运行。第三种是使用实时调度策略,比如SCHED_FIFO或SCHED_RR,配合优先级设置,虽然不严格独占,但能提高CPU占用率。此外,还有内核线程管理,比如禁用irqbalance,手动设置中断的亲和性,避免中断影响独占核心。 对于Windows系统,可能涉及到设置处理器亲和性,通过任务管理器或PowerShell命令将进程绑定到特定CPU。另外,使用Windows API在编程中设置亲和性掩码。还有Hyper-V的配置,为虚拟机分配独占CPU资源。 需要考虑的问题包括资源浪费,因为独占会导致其他进程无法使用该核心;配置复杂性,尤其是涉及内核参数和系统配置;以及硬件依赖性,需要多核CPU支持。 安全性方面,需要管理员权限才能进行这些操作,普通用户可能无法自行配置。此外,用户可能需要具体的步骤示例,比如如何在Linux中使用isolcpus,如何用taskset绑定进程。 需要验证这些方法的正确性,比如检查isolcpus的参数是否正确,taskset命令的使用是否有误。同时,提醒用户谨慎操作,错误的配置可能导致系统不稳定。 总结起来,回答需要结构清晰,分点说明定义、用途、实现方法(分系统)、注意事项,并给出示例帮助用户理解。确保使用中文,行内公式正确,独立公式单独成段,但这个问题可能不太涉及数学公式,但如果有涉及性能计算的地方,可能需要用LaTeX表达,比如提到某些算法的时间复杂度时,但可能这里不需要。所以主要按照用户的要求,用中文分步骤解释,结构清晰。</think>### 独占CPU的概念及实现方法 #### 1. **什么是独占CPU?** **独占CPU**指在操作系统中,将特定的CPU核心(或整个CPU)**完全分配给某个进程或线程**使用,确保其他任务无法占用该核心资源。 - 核心目标:**消除上下文切换**和**资源竞争**,提升关键任务的执行效率和确定性。 - 典型场景:高频交易、实时系统、科学计算、性能基准测试等对延迟敏感的场景。 --- #### 2. **独占CPU的实现方法** 实现方式因操作系统而异,以下是常见方案: ##### **Linux系统** **方法1:内核参数隔离(`isolcpus`)** 1. **修改内核启动参数**: 在`/etc/default/grub`文件中添加`isolcpus`参数(例如隔离CPU核心2和3): ```bash GRUB_CMDLINE_LINUX="isolcpus=2,3" ``` 更新配置后重启系统: ```bash sudo update-grub && sudo reboot ``` 2. **绑定进程到隔离核心**: 使用`taskset`命令将进程绑定到隔离的CPU核心: ```bash taskset -c 2,3 ./your_program ``` **方法2:cgroups限制(cpuset)** 1. **创建cpuset组**: ```bash sudo mkdir /sys/fs/cgroup/cpuset/exclusive_cpu ``` 2. **指定独占CPU核心**: ```bash echo "2-3" > /sys/fs/cgroup/cpuset/exclusive_cpu/cpuset.cpus ``` 3. **将进程加入cgroup**: ```bash echo $PID > /sys/fs/cgroup/cpuset/exclusive_cpu/tasks ``` **方法3:实时调度策略(SCHED_FIFO/SCHED_RR)** 通过提高优先级抢占CPU(需`root`权限): ```bash sudo chrt -f 99 ./your_program # SCHED_FIFO优先级99 ``` --- ##### **Windows系统** **方法1:任务管理器设置亲和性** 1. 打开任务管理器 → 详细信息 → 右键目标进程 → 设置亲和性 → 勾选指定CPU核心。 **方法2:PowerShell命令绑定** ```powershell $Process = Get-Process -Name "your_program" $Process.ProcessorAffinity = 0x0C # 二进制掩码(0x0C=1100,绑定CPU2和3) ``` **方法3:编程实现亲和性** 调用Windows API(C/C++示例): ```cpp #include <windows.h> DWORD_PTR affinity_mask = 1 << 2; // 绑定CPU2 SetProcessAffinityMask(GetCurrentProcess(), affinity_mask); ``` --- #### 3. **注意事项** - **资源浪费**:独占核心可能导致其他任务负载不均衡,需评估必要性。 - **权限要求**:需管理员权限(如Linux的`root`、Windows的Administrator)。 - **硬件依赖**:需多核CPU支持,且需确认CPU拓扑(如通过`lscpu`或`Get-WmiObject Win32_Processor`)。 - **中断干扰**:在Linux中,需手动设置中断亲和性,避免硬件中断影响独占核心: ```bash echo 0 > /proc/irq/XX/smp_affinity_list # 将中断XX绑定CPU0 ``` --- #### 4. **验证独占效果** - **Linux检查工具**: ```bash top -p $(pgrep your_program) # 按"F"选择显示P列(CPU亲和性) ``` - **Windows检查工具**: 使用Process Explorer查看进程的`CPU Affinity`属性。 --- ### 总结 独占CPU通过隔离核心绑定进程实现,适用于对性能要求严苛的场景,但需权衡资源利用率与稳定性。具体实现需结合操作系统和硬件环境选择合适方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值