linux内核线程绑定到单个核,linux 将进程或者线程绑定到指定的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

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

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

代码示例:

#define _GNU_SOURCE

#include

#include

#include

#include

#include

#include

/* 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: %d\n", 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:%s\n", strerror(errno));

return -1;

}

usleep(1000); /* 让当前的设置有足够时间生效*/

/*查看当前进程的cpu 亲和性*/

CPU_ZERO(&get);

if (sched_getaffinity(0, sizeof(get), &get) == -1) {

printf("get CPU affinity failue, ERROR:%s\n", 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: %d\n", getpid(), i);

}

}

sleep(10); //让程序停在这儿,方便top命令查看

return 0;

}

结果:

线程与cpu的绑定

#include

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

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

代码示例:

#define _GNU_SOURCE

#include

#include

#include

#include

#include

#include

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(), sizeof(mask), &mask) < 0) {

fprintf(stderr, "set thread affinity failed\n");

}

/* 查看cpu 亲和性(affinity)*/

CPU_ZERO(&get);

if (pthread_getaffinity_np(pthread_self(), sizeof(get), &get) < 0) {

fprintf(stderr, "get thread affinity failed\n");

}

/* 查看当前线程所运行的所有cpu*/

for (i = 0; i < cpus; i++) {

if (CPU_ISSET(i, &get)) {

printf("this thread %d is running in processor %d\n", (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 failed\n");

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(), sizeof(mask), &mask) < 0) {

fprintf(stderr, "set thread affinity failed\n");

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值