进程/线程绑定cpu方法探究

1、使用taskset指令

1)获取进程pid

[root@CENTOS57 eq]# ps aux | grep led
root       9240  0.0  0.0   6324   376 pts/0    S    07:40   0:00 ./ledThread
root       9242  0.0  0.0 112660   968 pts/0    S+   07:40   0:00 grep --color=auto led

2)查看进程当前运行在哪个cpu核上

p参数查看进程的绑定cpu核。

[root@CENTOS57 eq]# taskset -p 9240
pid 9240's current affinity mask: 2

显示的十进制数字2转换为2进制为10,每个1对应一个cpu,所以进程运行在第2个cpu核上。

3)指定进程运行在cpu3核上

pc参数绑定cpu核。

[root@CENTOS57 eq]# taskset -pc 3 9240
pid 9240's current affinity list: 2
pid 9240's new affinity list: 3

[root@CENTOS57 eq]# taskset -p 9240
pid 9240's current affinity mask: 8

cpu的标号是从0开始的,所以cpu3表示第4个cpu(第一个cpu的标号是0)。

至此,就把应用程序绑定到了cpu3上运行

4)启动程序时绑定cpu核

#启动时绑定到第二个cpu1
[root@CENTOS57 eq]# taskset -c 1 ./ledall &
[1] 3011

#查看确认绑定情况
[root@CENTOS57 eq]# taskset -p 3011
pid 3011's current affinity mask: 2

2、使用sched_setaffinity系统调用

sched_setaffinity可以将某个进程绑定到一个特定的CPU。

注意:在使用时,需要添加下面宏与头文件,并且顺序不可以颠倒。

#define _GNU_SOURCE    
#include <sched.h>
cpu_set_t mask;
CPU_ZERO(&mask);    //置空
CPU_SET(n,&mask);   //设置亲和力值,绑定cpu核到(n)核上
/* 设置进程号为pid的进程运行在mask所设定的CPU上
 * 第二个参数cpusetsize是mask所指定的数的长度
 * 通常设定为sizeof(cpu_set_t)
 * 如果pid的值为0,则表示指定的是当前进程 
 */
int sched_setaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);
int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);
/*
 获得pid所指示的进程的CPU位掩码,并将该掩码返回到mask所指向的结构中 
*/

例子1:pthread线程内部绑核

#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/sysinfo.h>
#include<unistd.h>

#define _GNU_SOURCE
#include<sched.h>
#include<ctype.h>
#include<string.h>
#include<pthread.h>
#define THREAD_MAX_NUM 200  //1个CPU内的最多进程数

int num=0;  //cpu中核数
void* threadFun(void* arg)  //arg  传递线程标号(自己定义)
{
    cpu_set_t mask;  //CPU核的掩码mask
    cpu_set_t get;   //获取cpu掩码
    int *a = (int *)arg; 
    int i;

    printf("the thread is:%d\n",*a);  //显示是第几个线程
    CPU_ZERO(&mask);    //置空
    CPU_SET(*a,&mask);   //设置亲和力值,绑定cpu核到(*a)核上
    if (sched_setaffinity(0, sizeof(mask), &mask) == -1)//设置线程CPU亲和力
    {
        printf("warning: could not set CPU affinity \n");
    }

    CPU_ZERO(&get);
    if (sched_getaffinity(0, sizeof(get), &get) == -1)//获取线程CPU亲和力
    {
         printf("warning: cound not get thread affinity, continuing...\n");
    }
    for (i = 0; i < num; i++)
    {
        if (CPU_ISSET(i, &get))//判断线程与哪个CPU有亲和力
        {
          printf("this thread %d is running processor : %d\n", i,i);
        }
    }

   return NULL;
}

int main(int argc, char* argv[])
{
   int tid[THREAD_MAX_NUM];
   int i;
   pthread_t thread[THREAD_MAX_NUM];

   num = sysconf(_SC_NPROCESSORS_CONF);  //获取核数for(i=0;i<num;i++)
   {
       tid[i] = i;  //每个线程必须有个tid[i]
       pthread_create(&thread[i],NULL,threadFun,(void*)&tid[i]);
   }
   for(i=0; i< num; i++)
   {
      pthread_join(thread[i],NULL);//等待所有的线程结束,线程为死循环所以CTRL+C结束
   }
   return 0;
}

 例子2:main主线程绑核

#define _GNU_SOURCE             /* See feature_test_macros(7) */
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sched.h>
#include <pthread.h>
 
void* testfunc(void* t) {
  while(1);
  return NULL; 
}
 
int main()
{
  cpu_set_t mask;
  printf("pid=%d\n", getpid());
  CPU_ZERO(&mask);
  CPU_SET(0, &mask);//将cpu0绑定
  sched_setaffinity(0, sizeof(cpu_set_t), &mask) ;
  
  pthread_t tid1;//创建线程1
  if (pthread_create(&tid1, NULL, (void *)testfunc, NULL) != 0) 
  {      
    fprintf(stderr, "thread create failed\n");
    return -1;   
  }
  pthread_join(tid1, NULL);
  return 0;
}

例子3:main主函数内部绑线程核

#define _GNU_SOURCE             /* See feature_test_macros(7) */
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sched.h>
#include <pthread.h>
 
void* testfunc(void* t) {
  int i = 3;
  while(i) {
     sleep(5);
     printf("tid=%d,cpu=%d\n",pthread_self(), sched_getcpu());
     i--;
  }return NULL; 
}
 
int main()
{
  cpu_set_t mask;
  printf("pid=%d\n", getpid());
  CPU_ZERO(&mask);
  
  pthread_t tid1;
  if (pthread_create(&tid1, NULL, (void *)testfunc, NULL) != 0) 
  {      
    fprintf(stderr, "thread create failed\n");
    return -1;   
  }
  pthread_t tid2;
  if (pthread_create(&tid2, NULL, (void *)testfunc, NULL) != 0) 
  {      
    fprintf(stderr, "thread create failed\n");
    return -1;   
  } 
  printf("tid1=%d,tid2=%d\n", tid1,tid2);
 
  CPU_SET(0, &mask);//绑定cpu0,线程绑定
  pthread_setaffinity_np(tid1, sizeof(cpu_set_t), &mask) ;
  
  //清除之前设置,重新设置绑定cpu3
  CPU_ZERO(&mask);
  CPU_SET(3, &mask);
  pthread_setaffinity_np(tid2, sizeof(cpu_set_t), &mask) ;
  
  pthread_join(tid1, NULL);
  pthread_join(tid1, NULL);
  return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值