Linux编程-让进程或线程运行在指定的CPU上

Linux编程-让进程或线程运行在指定的CPU上

为了让程序拥有更好的性能,有时候需要将进程或线程绑定到特定的CPU上,这样可以减少调度的开销和保护关键进程或线程。

1、绑定进程到指定的CPU

Linux提供一个接口,可以将进程绑定到特定的CPU:

#include <sched.h>
int sched_setaffinity(pid_t pid, size_t cpusetsize, const cpu_set_t *set);
int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *set);


参数:
pid:进程的id号,如果pid为0,则表示本进程
cpusetsize:set的大小
set:运行进程的CPU,可以通过以下函数操作set:

void CPU_ZERO(cpu_set_t *set); // Clears set, so that it contains no CPUs.
void CPU_SET(int cpu, cpu_set_t *set); // Add CPU cpu to set.
void CPU_CLR(int cpu, cpu_set_t *set); // Remove CPU cpu from set.
int  CPU_ISSET(int cpu, cpu_set_t *set); // Test to see if CPU cpu is a member of set.
int  CPU_COUNT(cpu_set_t * mask); //Return the number of CPUs in set.

 
进程绑定到指定CPU的演示程序如下: 

/*
*gcc process_test.c
*/

#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <math.h>
#include <sched.h>

void WasteTime(void)
{
    int abc = 1000;
    int tmp = 0;
    while(abc--)
        tmp = 10000*10000;

    sleep(1);
}

int main(int argc, char *argv[])
{
    cpu_set_t cpu_set;
    
    while(1)
    {
        CPU_ZERO(&cpu_set);
        CPU_SET(0, &cpu_set);
        if(sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0)
            perror("sched_setaffinity");
        WasteTime();
 
        CPU_ZERO(&cpu_set);
        CPU_SET(1, &cpu_set);
        if(sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0)
            perror("sched_setaffinity");
        WasteTime();
   
        CPU_ZERO(&cpu_set);
        CPU_SET(2, &cpu_set);
        if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0)
            perror("sched_setaffinity");
        WasteTime();
   
        CPU_ZERO(&cpu_set);
        CPU_SET(3, &cpu_set);
        if(sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0)
            perror("sched_setaffinity");
        WasteTime();
    }
    
    return 0;
}

测试:编译程序,之后运行,我编译出的文件名为out,执行下列命令,得到out1的PID:ps -elf | grep out1,之后输入命令:top -p 进程ID,接着输入f,选择P选项(移到P处,按下空格),按ESC退出,具体过程如下:


此时可以看到进程在cpu0 cpu1 cpu2 cpu3之间不停切换:

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的,没有冲突。

/*
*gcc thread_test.c -lpthread
*/

//#define _GNU_SOURCE
#include <stdio.h>
#include <math.h>
#include <pthread.h>
#include <unistd.h>
#include <sched.h>

void WasteTime(void)
{
    int abc = 1000;
    int temp = 0;

    while(abc--)
        temp = 10000*10000;

    sleep(1);
}

void *thread_func1(void *param)
{
    cpu_set_t cpu_set;
    while(1)
    {
        CPU_ZERO(&cpu_set);
        CPU_SET(1, &cpu_set);

        if (pthread_setaffinity_np(pthread_self(), sizeof(cpu_set),&cpu_set) < 0)
            perror("pthread_setaffinity_np");
        WasteTime();

        CPU_ZERO(&cpu_set);
        CPU_SET(2, &cpu_set);

        if (pthread_setaffinity_np(pthread_self(), sizeof(cpu_set),&cpu_set) < 0)
            perror("pthread_setaffinity_np");
        WasteTime();
    }
}

void *thread_func2(void *param)
{
    cpu_set_t cpu_set;
    while(1)
    {
        CPU_ZERO(&cpu_set);
        CPU_SET(3, &cpu_set);

        if (pthread_setaffinity_np(pthread_self(), sizeof(cpu_set),&cpu_set) < 0)
            perror("pthread_setaffinity_np");
        WasteTime();
    }
}

int main(int argc, char *argv[])
{
    pthread_t my_thread;
    cpu_set_t cpu_set;
    CPU_ZERO(&cpu_set);
    CPU_SET(0, &cpu_set);
    if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0)
        perror("sched_setaffinity");

    if (pthread_create(&my_thread, NULL, thread_func1,NULL) != 0)
        perror("pthread_create");
    if (pthread_create(&my_thread, NULL, thread_func2,NULL) != 0)
        perror("pthread_create");

    while(1)
        WasteTime();

    pthread_exit(NULL);
}

测试:编译程序,之后运行,我编译出的文件名为a.out,执行下列命令,得到a.out的PID:ps -elf | grep a.out,之后输入命令:top -H -p? 进程ID,接着输入f,选择P选项(移到P处,按下空格)和nTH选项,按ESC退出,具体过程如下:
(和上图类似)

可以看到主线程一直保持在cpu0,一个线程在cpu1 cpu2之间切换,另一个线程一直保持在cpu3。


 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值