首页 > 其他分享 >线程绑定cpu核心的代码研究

线程绑定cpu核心的代码研究

时间:2024-10-31 18:20:46浏览次数:5  
标签:绑定 mask CPU 线程 pthread include 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;
}

标签:绑定,mask,CPU,线程,pthread,include,cpu
From: https://www.cnblogs.com/chromeplugin/p/18518602

相关文章

  • 线程池ThreadPoolExecutor配合callable获得线程执行结果
    此处记录使用callable创建线程,使用线程池执行,看下是否有进行线程复用并且FutureTask返回结果线程创建publicclassMyCallableBakeUserimplementsCallable<String>{privateinta;publicMyCallableBakeUser(inta){this.a=a;}@Overrid......
  • 使用ThreadPoolExecutor线程池消化线程执行代码
    此处记录一个使用ThreadPoolExecutor线程池的demo线程代码publicclassExcutorRunnableimplementsRunnable{@Overridepublicvoidrun(){System.out.println(Thread.currentThread().getName()+":线程执行666");try{Thread.......
  • 线程池原理
    线程池是一种多线程处理方式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中。如果某个线程在托管代码中空闲(如正在等待某个事件),则线程池将插入另一个辅助线程来使所有......
  • 多线程在打包工具中的运用
    我们是袋鼠云数栈UED团队,致力于打造优秀的一站式数据中台产品。我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值。本文作者:UED团队现代操作系统都是「多任务」的,也就是操作系统可以「并发」处理多个任务,比如可以在浏览页面的时候同时播放音乐。但是,一般来说我......
  • BitNet.cpp:革新性的1比特LLM推理框架,让CPU也能驾驭百亿参数大模型!
    ......
  • 多线程编程 Linux环境
    进程和线程相同点:都是参与时间片轮转的任务,都有5个状态不同点:线程不能独立存在,只能隶属于创建它的进程进程实际上是线程的容器,任何进程至少包含一个称为主线程的线程,执行main函数所在的执行序列,这个线程是系统为进程自动创建而其余线程则进程通过调用相关函数来创建进......
  • C++多线程应用
    一个进程就是一个程序,一个程序里不止一个功能,每个功能的实现就可以交给一个线程去完成。一个进程就像是一个工程,这个工程里,有设计,有监理,有施工,就相当于三个线程,各干各的又相互配合。https://cplusplus.com/reference/thread/thread/thread/是C++的官方参考,个人觉得比较权威,比经......
  • 【操作系统】1.进程和线程
    1.进程(Process)定义:进程是操作系统资源分配的基本单位,一个进程包含了程序的代码、数据、文件、内存等资源。每个进程之间都是独立的,拥有独立的地址空间。特性:独立性:每个进程之间是独立的,不能直接访问其他进程的内存空间。资源占用:进程会占用较多的系统资源,例如内存、文件描......
  • Linux系统基础-多线程超详细讲解(3)_线程互斥同步和条件变量
    个人主页:C++忠实粉丝欢迎点赞......
  • 把代码绑定到WPF中的textblock中
    在WPF中,将数据绑定到TextBlock控件中是一个常见的操作,这样可以动态显示数据源中的数据。以下是如何将数据绑定到TextBlock的步骤:定义数据源:首先,你需要有一个数据源,它可以是一个属性,这个属性需要实现INotifyPropertyChanged接口以便在数据变化时通知UI更新。设置DataContex......