为了让程序拥有更好的性能,有时候需要将进程或线程绑定到特定的CPU,这样可以减少调度的开销和保护关键进程或线程
1. 进程绑定到CPU
Linux提供一个接口,可以将进程绑定到特定的CPU:
#include <sched.h>
int sched_setaffinity(pid_t pid, size_t cpusetsize, const cpu_set_t *mask);
int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);
参数
pid:进程的id号,如果pid为0,则表示本进程
cpusetsize:mask的大小
mask:运行进程的CPU,可以通过以下函数操作mask
#define CPU_SET(cpu, cpusetp) //设置cpu
#define CPU_CLR(cpu, cpusetp) //删除cpu
#define CPU_ISSET(cpu, cpusetp) //判断cpu
#define CPU_ZERO(cpusetp) //初始化为0
2.线程绑定到CPU
不仅仅进程可以绑定到CPU,线程也可以。Linux提供一个接口,可以将线程绑定到特定的CPU:
#include <pthread.h>
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, cpu_set_t *cpuset);
该接口与进程绑定到CPU的接口的使用方法基本一致。
当进程绑定到特定的CPU之后,线程还是可以绑定到其他的CPU的,没有冲突。
具体代码如下:
#define _GNU_SOURCE
#include <stdio.h>
#include <math.h>
#include <pthread.h>
#include <unistd.h>
#include <sched.h>
/*******************
* 等待时间
*******************/
void WasteTime()
{
int abc = 10000000;
while(abc--)
{
int tmp = 10000*10000;
}
sleep(1);
}
/************************************************************************
* 这个线程不停在CPU0 CPU1上切换,在有4核的CPU前提下
***************************************************************************/
void *thread_func(void *param)
{
cpu_set_t mask;
while(1)
{
CPU_ZERO(&mask);
CPU_SET(0, &mask);
if (pthread_setaffinity_np(pthread_self(), sizeof(mask),&mask) < 0) {
perror("pthread_setaffinity_np");
}
WasteTime();
CPU_ZERO(&mask);
CPU_SET(1, &mask);
if (pthread_setaffinity_np(pthread_self(), sizeof(mask),
&mask) < 0) {
perror("pthread_setaffinity_np");
}
WasteTime();
}
}
/************************************************************************
* 这个线程不停在CPU2 CPU3上切换,在有4核的CPU前提下
***************************************************************************/
void *thread_func1(void *param)
{
cpu_set_t mask;
while(1)
{
CPU_ZERO(&mask);
CPU_SET(2, &mask);
if (pthread_setaffinity_np(pthread_self(), sizeof(mask),
&mask) < 0) {
perror("pthread_setaffinity_np");
}
WasteTime();
CPU_ZERO(&mask);
CPU_SET(3, &mask);
if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0) {
perror("pthread_setaffinity_np");
}
WasteTime();
}
}
int main(int argc, char *argv[])
{
cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET(0, &mask); //将当前的进程绑定在CPU0 上
if (sched_setaffinity(0, sizeof(mask), &mask) < 0) {
perror("sched_setaffinity");
}
pthread_t my_thread;
if (pthread_create(&my_thread, NULL, thread_func,
NULL) != 0) {
perror("pthread_create");
}
if (pthread_create(&my_thread, NULL, thread_func1,
NULL) != 0) {
perror("pthread_create");
}
while(1) { WasteTime(); }
pthread_exit(NULL);
}
通过top ,按H后可以看到一个进程绑定在CPU0 上,一个线程在CPU0 CPU1 上不停切换,另一个线程在CPU2 CPU3 上不停切换.pid = 512 是进程