最近打算写个小程序, 需要控制使用的是哪个 cpu 内核,所以做了一些调查, 整理一下分享给大家。
ps: 因为毕业季很久没有写博客了, 以后继续。 顺便鄙视一下那些转载不声明出处的, by watkins.song
pps: 最近有了个新的id, 因为在Oracle, wei.x.song, 不知到以后用哪个id比较酷一点
主要参考:
http://www.gnu.org/software/libc/manual/html_node/CPU-Affinity.html/
http://stackoverflow.com/questions/7296963/gnu-source-and-use-gnu
https://gcc.gnu.org/ml/fortran/2005-10/msg00365.html
设置想要使用的cpu内核, 因为现在绝大部分都是多内核的cpu, 其实就是设置cpu的affinity,
网上找的例子这样写:
#include <stdio.h> #include <math.h> #include <unistd.h> #include <sys/times.h> #define __USE_GNU #include <sched.h>
先看一下我总结的代码:
#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <sched.h> #include <unistd.h> #include <sys/times.h> void set_cpu(int id); int main(void) { puts("cpu affinity set"); set_cpu(0x0003); while(1) { //sleep(10); //printf("in the while\n"); } return 1; } // setup the cpu set of this program to run on void set_cpu(int id) { cpu_set_t mask; CPU_ZERO(&mask); CPU_SET(id, &mask); if (sched_setaffinity(0, sizeof(mask), &mask) == -1) { fprintf(stderr, "warning: could not set CPU affinity/n"); } }
#define _GNU_SOURCE
这个宏定义一定要放在代码文件的最开始位置, 即使你把它放在了<sched.h>之前,但是如果不是文件最开始部分,那么也编译不了。
看一下系统的运行:
可以看到在指定的cpu上运行的程序。
然后, 看一下具体的一些细节。
cpu_set_t 是一个cpu集合, 用于表明使用哪些内核, 所以也可以称为是mask, cpu_set_t的实现如下:
typedef struct { __cpu_mask __bits[__CPU_SETSIZE / __NCPUBITS]; } cpu_set_t;
/* Type for array elements in 'cpu_set_t'. */ typedef unsigned long int __cpu_mask;
运行的时候, 没有运行CPU_ZERO() 之前 __bits = {0, 140737351860832, 10, 140737354104832, 17, 140737348450122, 16, 17, 10, 4196320, 140737488347648, 140737348456117, 140737351860832, 140737348456959, 140737351860832, 16}
然后运行CPU_ZERO() 将cpu_set都重置为0, 这个时候:
__bits = {0 <repeats 16 times>}
sched_setaffinity(0, sizeof(mask), &mask) == -1 这句代码则根据已经设置的cpu mask设置当前进程采用哪个cpu内核运行。
sched_setaffinity()的原型函数为:
int sched_setaffinity (pid_t
pid, size_t cpusetsize, const cpu_set_t *cpuset)
This function installs the cpusetsize bytes long affinity mask pointed to by cpuset for the process or thread with the ID pid. If successful the function returns zero and the scheduler will in future take the affinity information into account.
If the function fails it will return -1
and errno
is set to the error code:
ESRCH
EFAULT
EINVAL
This function is a GNU extension and is declared in sched.h.
来看一下 sched.h 头文件, 头文件中有这样一段:
#ifdef __USE_GNU /* Access macros for `cpu_set'. */ # define CPU_SETSIZE __CPU_SETSIZE # define CPU_SET(cpu, cpusetp) __CPU_SET_S (cpu, sizeof (cpu_set_t), cpusetp) # define CPU_CLR(cpu, cpusetp) __CPU_CLR_S (cpu, sizeof (cpu_set_t), cpusetp) # define CPU_ISSET(cpu, cpusetp) __CPU_ISSET_S (cpu, sizeof (cpu_set_t), cpusetp) # define CPU_ZERO(cpusetp) __CPU_ZERO_S (sizeof (cpu_set_t), cpusetp) # define CPU_COUNT(cpusetp) __CPU_COUNT_S (sizeof (cpu_set_t), cpusetp) # define CPU_SET_S(cpu, setsize, cpusetp) __CPU_SET_S (cpu, setsize, cpusetp) # define CPU_CLR_S(cpu, setsize, cpusetp) __CPU_CLR_S (cpu, setsize, cpusetp) # define CPU_ISSET_S(cpu, setsize, cpusetp) __CPU_ISSET_S (cpu, setsize, cpusetp) # define CPU_ZERO_S(setsize, cpusetp) __CPU_ZERO_S (setsize, cpusetp) # define CPU_COUNT_S(setsize, cpusetp) __CPU_COUNT_S (setsize, cpusetp) # define CPU_EQUAL(cpusetp1, cpusetp2) __CPU_EQUAL_S (sizeof (cpu_set_t), cpusetp1, cpusetp2) # define CPU_EQUAL_S(setsize, cpusetp1, cpusetp2) __CPU_EQUAL_S (setsize, cpusetp1, cpusetp2) # define CPU_AND(destset, srcset1, srcset2) __CPU_OP_S (sizeof (cpu_set_t), destset, srcset1, srcset2, &) # define CPU_OR(destset, srcset1, srcset2) __CPU_OP_S (sizeof (cpu_set_t), destset, srcset1, srcset2, |) # define CPU_XOR(destset, srcset1, srcset2) __CPU_OP_S (sizeof (cpu_set_t), destset, srcset1, srcset2, ^) # define CPU_AND_S(setsize, destset, srcset1, srcset2) __CPU_OP_S (setsize, destset, srcset1, srcset2, &) # define CPU_OR_S(setsize, destset, srcset1, srcset2) __CPU_OP_S (setsize, destset, srcset1, srcset2, |) # define CPU_XOR_S(setsize, destset, srcset1, srcset2) __CPU_OP_S (setsize, destset, srcset1, srcset2, ^) # define CPU_ALLOC_SIZE(count) __CPU_ALLOC_SIZE (count) # define CPU_ALLOC(count) __CPU_ALLOC (count) # define CPU_FREE(cpuset) __CPU_FREE (cpuset) /* Set the CPU affinity for a task */ extern int sched_setaffinity (__pid_t __pid, size_t __cpusetsize, __const cpu_set_t *__cpuset) __THROW; /* Get the CPU affinity for a task */ extern int sched_getaffinity (__pid_t __pid, size_t __cpusetsize, cpu_set_t *__cpuset) __THROW; #endif
#ifdef _GNU_SOURCE # define __USE_GNU 1 #endif
所以在我们程序的最开始位置, 定义了 _GNU_SOURCE 这个宏定义
c语言设置cpu affinity (设置程序需要使用的cpu内核) cpu mask,布布扣,bubuko.com
c语言设置cpu affinity (设置程序需要使用的cpu内核) cpu mask
原文地址:http://blog.csdn.net/watkinsong/article/details/28418911