加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

linux 将进程或者线程绑定到指定的cpu上

发布时间:2020-12-14 01:51:39 所属栏目:Linux 来源:网络整理
导读:基本概念 cpu亲和性(affinity) CPU的亲和性, 就是进程要在指定的 CPU 上尽量长时间地运行而不被迁移到其他处理器,也称为CPU关联性;再简单的点的描述就将指定的进程或线程绑定到相应的cpu上;在多核运行的机器上,每个CPU本身自己会有缓存,缓存着进程使

基本概念

cpu亲和性(affinity)
CPU的亲和性, 就是进程要在指定的 CPU 上尽量长时间地运行而不被迁移到其他处理器,也称为CPU关联性;再简单的点的描述就将指定的进程或线程绑定到相应的cpu上;在多核运行的机器上,每个CPU本身自己会有缓存,缓存着进程使用的信息,而进程可能会被OS调度到其他CPU上,如此,CPU cache命中率就低了,当绑定CPU后,程序就会一直在指定的cpu跑,不会由操作系统调度到其他CPU上,性能有一定的提高。

软亲和性(affinity)
就是进程要在指定的 CPU 上尽量长时间地运行而不被迁移到其他处理器,Linux 内核进程调度器天生就具有被称为 软 CPU 亲和性(affinity) 的特性,这意味着进程通常不会在处理器之间频繁迁移。这种状态正是我们希望的,因为进程迁移的频率小就意味着产生的负载小。
硬亲和性(affinity)
简单来说就是利用linux内核提供给用户的API,强行将进程或者线程绑定到某一个指定的cpu核运行。

相关函数

void CPU_ZERO (cpu_set_t *set)  /*这个宏对 CPU 集 set 进行初始化,将其设置为空集。*/
void CPU_SET (int cpu,cpu_set_t *set)  /*这个宏将 指定的 cpu 加入 CPU 集 set 中*/
void CPU_CLR (int cpu,cpu_set_t *set)  /*这个宏将 指定的 cpu 从 CPU 集 set 中删除。*/
int CPU_ISSET (int cpu,const cpu_set_t *set)  /*如果 cpu 是 CPU 集 set 的一员,这个宏就返回一个非零值(true),否则就返回零(false)。*/

进程与cpu的绑定

#include <sched.h>

int sched_setaffinity(pid_t pid,size_t cpusetsize,const cpu_set_t *mask);
int sched_getaffinity(pid_t pid,const cpu_set_t *mask);

代码示例:

#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

/* sysconf( _SC_NPROCESSORS_CONF ) 查看cpu的个数;打印用%ld长整。
 * sysconf( _SC_NPROCESSORS_ONLN ) 查看在使用的cpu个数;打印用%ld长整 */
int main(int argc,char **argv)
{
    int cpus = 0;
    int  i = 0;
    cpu_set_t mask;
    cpu_set_t get;

    cpus = sysconf(_SC_NPROCESSORS_CONF);
    printf("cpus: %dn",cpus);

    CPU_ZERO(&mask);    /* 初始化set集,将set置为空*/
    CPU_SET(0,&mask);  /* 依次将0、1、2、3号cpu加入到集合,前提是你的机器是多核处理器*/
    CPU_SET(1,&mask);
    CPU_SET(2,&mask);
    CPU_SET(3,&mask);
    
    /*设置cpu 亲和性(affinity)*/
    if (sched_setaffinity(0,sizeof(mask),&mask) == -1) {
        printf("Set CPU affinity failue,ERROR:%sn",strerror(errno));
        return -1; 
    }   
    usleep(1000); /* 让当前的设置有足够时间生效*/

    /*查看当前进程的cpu 亲和性*/
    CPU_ZERO(&get);
    if (sched_getaffinity(0,sizeof(get),&get) == -1) {
        printf("get CPU affinity failue,strerror(errno));
        return -1; 
    }   
    
    /*查看运行在当前进程的cpu*/
    for(i = 0; i < cpus; i++) {

        if (CPU_ISSET(i,&get)) { /*查看cpu i 是否在get 集合当中*/
            printf("this process %d of running processor: %dn",getpid(),i); 
        }    
    }
    sleep(10); //让程序停在这儿,方便top命令查看
       
    return 0;
}

结果:

线程与cpu的绑定

#include <pthread.h>

int pthread_setaffinity_np(pthread_t thread,const cpu_set_t *cpuset);
int pthread_getaffinity_np(pthread_t thread,const cpu_set_t *cpuset);

代码示例:

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sched.h>

void *testfunc(void *arg)
{
    int i,cpus = 0;
    cpu_set_t mask;
    cpu_set_t get;

    cpus = sysconf(_SC_NPROCESSORS_CONF);
    printf("this system has %d processor(s)n",cpus);
    
    CPU_ZERO(&mask);
    for (i = 0; i < 4; i++) { /*将0、1、2、3添加到集合中*/
        CPU_SET(i,&mask);
    }   

    /* 设置cpu 亲和性(affinity)*/
    if (pthread_setaffinity_np(pthread_self(),&mask) < 0) {
        fprintf(stderr,"set thread affinity failedn");
    }   
    
    /* 查看cpu 亲和性(affinity)*/
    CPU_ZERO(&get);
    if (pthread_getaffinity_np(pthread_self(),&get) < 0) {
        fprintf(stderr,"get thread affinity failedn");
    }   

    /* 查看当前线程所运行的所有cpu*/
    for (i = 0; i < cpus; i++) {
        if (CPU_ISSET(i,&get)) {
            printf("this thread %d is running in processor %dn",(int)pthread_self(),i); 
        }   
    }   
    sleep(3); //查看
    
    pthread_exit(NULL);
}
 
int main(int argc,char *argv[])
{
    pthread_t tid;
    if (pthread_create(&tid,NULL,(void *)testfunc,NULL) != 0) {
        fprintf(stderr,"thread create failedn");
        return -1; 
    }   

    pthread_join(tid,NULL);
    return 0;
}

结果:

指定在哪个CPU上运行:

void *threadfunc(void *arg)
{
    cpu_set_t mask;
    
    cpu_set_t mask;
    int cpuid = 1;
    CPU_ZERO(&mask);
    CPU_SET(cpuid,&mask);

    /* 设置cpu 亲和性(affinity)*/
    if (pthread_setaffinity_np(pthread_self(),"set thread affinity failedn");
    }       
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读