首页 > 使用 sched_setaffinity 将线程绑到CPU核上运行

使用 sched_setaffinity 将线程绑到CPU核上运行

linux 提供CPU调度函数,可以将CPU某一个核和指定的线程绑定到一块运行。

这样能够充分利用CPU,且减少了不同CPU核之间的切换,尤其是在IO密集型压力之下能够提供较为友好的性能。

通过sched_setaffinity 设置 CPU 亲和力的掩码,从而将该线程或者进程和指定的CPU绑定

一个CPU的亲合力掩码用一个cpu_set_t结构体来表示一个CPU集合,下面的几个宏分别对这个掩码集进行操作:

CPU_ZERO() 清空一个集合

CPU_SET()CPU_CLR()分别对将一个给定的CPU号加到一个集合或者从一个集合中去掉.

CPU_ISSET()检查一个CPU号是否在这个集合中

  • 头文件 sched.h
  • sched_setaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask)

    该函数设置进程为pid的这个进程,让它运行在mask所设定的CPU上.
    • 如果pid的值为0,则表示指定的是当前进程,使当前进程运行在mask所设定的那些CPU上.
    • 第二个参数cpusetsize是mask所指定的数的长度.通常设定为sizeof(cpu_set_t).如果当前pid所指定的进程此时没有运行在mask所指定的任意一个CPU上,则该指定的进程会从其它CPU上迁移到mask的指定的一个CPU上运行.
    • mask 即用户 通过CPU_SET 接口,线程ID 绑定刀片集合中的一个CPU上,使用mask来表示cpu集合中的CPU
  • sched_getaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask)

    该函数获得pid所指示的进程的CPU位掩码,并将该掩码返回到mask所指向的结构中.即获得指定pid当前可以运行在哪些CPU上.同样,如果pid的值为0.也表示的是当前进程

使用方式如下:

#include 
#include 
#include 
#include 
#include #define __USE_GNU
#include 
#include int num;void *thread_func1(void *arg) { cpu_set_t mask;  //CPU核的集合cpu_set_t get;   //获取在集合中的CPUint *a = (int*)arg; printf("the a is:%d
",*a);  //显示是第几个线程CPU_ZERO(&mask);    //置空CPU_SET(*a,&mask);   // 将当前线程和CPU绑定if(sched_setaffinity(0, sizeof(mask), &mask)) { printf("warning ! set affinity failed! 
");      } else { while (1){ CPU_ZERO(&get);if (sched_getaffinity(0, sizeof(get), &get) == -1)//获取线程CPU亲和力{ printf("warning: cound not get thread affinity, continuing...
");}int i;for (i = 0; i < num; i++){ if (CPU_ISSET(i, &get))//判断线程与哪个CPU有亲和力{ printf("this thread %d is running processor : %d
", i,i);}}}}return NULL; 
}void *thread_func2(void *arg) { cpu_set_t mask;  //CPU核的集合cpu_set_t get;   //获取在集合中的CPUint *a = (int*)arg; printf("the a is:%d
",*a);  //显示是第几个线程CPU_ZERO(&mask);    //置空CPU_SET(*a,&mask);   // 将当前线程和CPU绑定if(sched_setaffinity(0, sizeof(mask), &mask) == -1) { printf("warning ! set affinity failed! 
");      } else { while (1){ CPU_ZERO(&get);if (sched_getaffinity(0, sizeof(get), &get) == -1)//获取线程CPU亲和力{ printf("warning: cound not get thread affinity, continuing...
");}int i;for (i = 0; i < num; i++){ if (CPU_ISSET(i, &get))//判断线程与哪个CPU有亲和力{ printf("this thread %d is running processor : %d
", i,i);}}}}return NULL; 
}int main() { pthread_t t1;pthread_t t2;int t_1 = 0;int t_2 = 1;// 获取CPU核数num = sysconf(_SC_NPROCESSORS_CONF);// 需要传入t_1,t_2,来作为线程的参数,用来核CPU核绑定pthread_create(&t1, NULL, (void *)thread_func1,&t_1);pthread_create(&t2, NULL, (void *)thread_func2,&t_2);pthread_join(t1, NULL);pthread_join(t2, NULL);printf("main thread end
");return 0;
}

如果使用到pthread,则需要将pthread.h 放到sched.h之后,并在sched.h之前声明#define __USE_GNU

否则会出现undefined reference CPU_ZERO等错误

编译:

gcc sched_cpu.c -o sched_cpu -pthread

以上代码将两个线程分别绑定到0,1号CPU上

运行后的CPU 效果图如下:

在这里插入图片描述

更多相关:

  • CPU 原始文件路径mind-Mapping CPU上下文切换 CPU使用率...

  • 让CPU占用率曲线听你指挥  问题  写一个程序,让用户来决定Windows任务管理器(Task Manager)的CPU占用率。程序越精简越好,计算机语言不限。例如,可以实现下面三种情况:  1. CPU的占用率固定在50%,为一条直线;  2. CPU的占用率为一条直线,但是具体占用率由命令行参数决定(参数范围1~ 100); ...

  •   虽然驱动版的出来到现在也有好多年了,不过一直不打算发布。原因还是当初那个:CPU没有达到1%以下。       前些时候无意中在MSDN看到NDIS里数据包分配的文档,感觉之前犯了个大错误:数据包资源每次都是按申请/发送/释放的流程。文档中提到数据包资源的重用而不必申请释放,可以减少开销。原以为找到了问题的关键,可以实现当初的愿望...

  • 多线程有什么好处?提高CPU的利用率,更好地利用系统资源,使用Monitor类可以同步静态/实例化的方法的全部代码或者部分代码段,使用不同的同步类创建自己的同步机制。多线程指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程提升整体处理性能。多线程是指程序中包含多个执行流,即...

  • Step1:在界面主函数的构造函数中初始化多线程 auto mythread = new QThread(); //新建connect(mythread , &QThread::finished, mythread, &QObject::deleteLater);//线程运行结束后释放内存object1->moveToThread...

  • 一、thread的基本用法 参见C++使用thread类多线程编程 。 二、类外使用多线程,访问类的成员 这几种方式,新建线程都是在类外,然后通过把友元函数或者成员函数作为thread参数。 #include #include #include using namesp...

  • 本博文是根据中科大信息学院谭立湘老师的课件加上自己的理解整理出来的 ************************************************************************************ NVIDIA在2007年推出CUDA这个统一计算架构 CUDA的基本思想是支持大量的线程级并...

  • 一、parallel communication patterns   并行通信模式 Map:映射,在特定的位置读取和写入。 Gather:收集,从多个不同的位置读入,写入一个位置。 Scatter:分发,写入多个位置。 Transpose转置 结构数组缩写为AOS,数组结构缩写为SOA 转置运算是指任务重新排序内存中的数...