`

Linux中线程与CPU核的绑定

阅读更多
最近在对项目进行性能优化,由于在多核平台上,所以了解了些进程、线程绑定cpu核的问题,在这里将所学记录一下。
    不管是线程还是进程,都是通过设置亲和性(affinity)来达到目的。对于进程的情况,一般是使用sched_setaffinity这个函数来实现,网上讲的也比较多,这里主要讲一下线程的情况。
    与进程的情况相似,线程亲和性的设置和获取主要通过下面两个函数来实现:
    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_set_t这个结构体了。这个结构体的理解类似于select中的fd_set,可以理解为cpu集,也是通过约定好的宏来进行清除、设置以及判断:
   //初始化,设为空
      void CPU_ZERO (cpu_set_t *set);
      //将某个cpu加入cpu集中
       void CPU_SET (int cpu, cpu_set_t *set);
       //将某个cpu从cpu集中移出
       void CPU_CLR (int cpu, cpu_set_t *set);
       //判断某个cpu是否已在cpu集中设置了
       int CPU_ISSET (int cpu, const cpu_set_t *set);
       cpu集可以认为是一个掩码,每个设置的位都对应一个可以合法调度的 cpu,而未设置的位则对应一个不可调度的 CPU。换而言之,线程都被绑定了,只能在那些对应位被设置了的处理器上运行。通常,掩码中的所有位都被置位了,也就是可以在所有的cpu中调度。      
      以下为测试代码:
点击(此处)折叠或打开
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sched.h>

void *myfun(void *arg)
{
    cpu_set_t mask;
    cpu_set_t get;
    char buf[256];
    int i;
    int j;
    int num = sysconf(_SC_NPROCESSORS_CONF);
    printf("system has %d processor(s)\n", num);

    for (i = 0; i < num; i++) {
        CPU_ZERO(&mask);
        CPU_SET(i, &mask);
        if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0) {
            fprintf(stderr, "set thread affinity failed\n");
        }
        CPU_ZERO(&get);
        if (pthread_getaffinity_np(pthread_self(), sizeof(get), &get) < 0) {
            fprintf(stderr, "get thread affinity failed\n");
        }
        for (j = 0; j < num; j++) {
            if (CPU_ISSET(j, &get)) {
                printf("thread %d is running in processor %d\n", (int)pthread_self(), j);
            }
        }
        j = 0;
        while (j++ < 100000000) {
            memset(buf, 0, sizeof(buf));
        }
    }
    pthread_exit(NULL);
}

int main(int argc, char *argv[])
{
    pthread_t tid;
    if (pthread_create(&tid, NULL, (void *)myfun, NULL) != 0) {
        fprintf(stderr, "thread create failed\n");
        return -1;
    }
    pthread_join(tid, NULL);
    return 0;
}
       这段代码将使myfun线程在所有cpu中依次执行一段时间,在我的四核cpu上,执行结果为  :
       system has 4 processor(s)       
       thread 1095604544 is running in processor 0       
       thread 1095604544 is running in processor 1       
       thread 1095604544 is running in processor 2       
       thread 1095604544 is running in processor 3
       在一些嵌入式设备中,运行的进程线程比较单一,如果指定进程线程运行于特定的cpu核,减少进程、线程的核间切换,有可能可以获得更高的性能。
------------------------------2---------------------------------------

在服务器上,我们经常会有多个CPU的情况,而此时如果把进程都绑定在一个CPU上,那么对资源太多浪费了,下面的代码就实现了如何将程序绑定在不同的cpu上。传入参数代表绑定第几个cpu(从0开始计算)

//cpu_test.cpp
#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/sysinfo.h>
#include<unistd.h>
//#define __USE_GNU
#include<sched.h>
#include<ctype.h>
#include<string.h>
int main(int argc, char* argv[])
{
        int num = sysconf(_SC_NPROCESSORS_CONF);
        int created_thread = 0;
        int myid;
        int i;
        int j = 0;
        cpu_set_t mask;
        cpu_set_t get;
        if (argc != 2)
        {
                printf(“usage : ./cpu num\n”);
                exit(1);
        }
        myid = atoi(argv[1]);
        printf(“system has %i processor(s). \n”, num);
        CPU_ZERO(&mask);
        CPU_SET(myid, &mask);
        if (sched_setaffinity(0, sizeof(mask), &mask) == -1)
        {
                printf(“warning: could not set CPU affinity, continuing…\n”);
        }
        while (1)
        {
    usleep(10000);
                CPU_ZERO(&get);
                if (sched_getaffinity(0, sizeof(get), &get) == -1)
                {
                        printf(“warning: cound not get cpu affinity, continuing…\n”);
                }
                for (i = 0; i < num; i++)
                {
                        if (CPU_ISSET(i, &get))
                        {
                                printf(“this process %d is running processor : %d\n”,getpid(), i);
                        }
                }
        }
        return 0;
}
//g++ cpu_test.cpp -o cpu_test
分享到:
评论

相关推荐

    安卓 进程/线程绑定cpu

    本项目通过一个Gradle项目展示了如何实现这一功能,并提供了`adb shell ps -t -p -c`命令来查看系统中线程和进程的CPU绑定情况。 首先,我们需要理解安卓系统中的进程和线程概念。在安卓系统中,每个应用都是一个...

    线程/进程绑定CPU代码

    在CSDN博客链接中提到的文章,作者可能详细介绍了如何在Linux或Windows系统中实现线程或进程的CPU绑定。在Linux中,可以使用`sched_setaffinity`函数来设置进程或线程的亲和性,该函数允许我们指定一个CPU掩码,决定...

    多核线程绑定

    创建一个线程,并将该线程绑定到多核cpu中,不占用主线程的资源,这样可以在所开的线程中做一些动作,不会影响主线程中的动作。应用:客户将所有的刷新动作交给主线程完成时,可能拖动鼠标,窗口均在不断的刷新,CPU...

    Linux下进程绑定多CPU运行

    这个程序可能包含了上述`sched_setaffinity`和`sched_getaffinity`的使用示例,通过编译和运行,我们可以更直观地理解如何在代码层面控制进程的CPU绑定。 五、应用场景 1. 性能优化:对于计算密集型任务,绑定进程...

    利用OpenMP线程绑定技术提升多核平台应用性能

    - **compact模式**: 将线程尽可能紧密地绑定在一起,例如,在双CPU系统中,先将线程绑定到第一个CPU的所有核心上,然后再绑定到第二个CPU的核心上。 - **scatter模式**: 尽量将线程分散到不同的核心上,以减少竞争。...

    Linux多线程、Linux网络编程

    通过阅读《Linux多线程编程手册》和《Linux网络编程》这两本书,你可以深入学习这两个主题,掌握如何在Linux环境中编写高效的多线程网络应用。书中不仅会涵盖上述理论知识,还会提供丰富的示例代码,帮助你更好地...

    linux多定时器多线程

    在Linux操作系统中,多线程和多定时器是两种强大的技术,它们被广泛应用于各种复杂的系统和服务中。本文将深入探讨如何在Linux环境下利用多线程和多定时器来实现不同任务的并发执行,以及它们如何协同工作以提高程序...

    linux多线程设计及示例

    在Linux系统中,多线程是一种并发编程技术,允许程序同时执行多个独立的执行流,每个执行流称为一个线程。线程共享同一进程的内存空间,因此它们之间的通信更为高效。本文将深入探讨Linux环境下多线程的设计、创建、...

    linux多线程编程

    在探索Linux多线程编程之前,我们首先需要理解线程的基本概念及其在Linux环境中的应用。线程是进程的一部分,它允许一个进程执行多个指令序列。与传统的UNIX进程只包含一个执行线程不同,多线程技术将一个进程分解为...

    Linux多线程编程手册,linux多线程编程手册pdf,C,C++

    在Linux系统中,多线程编程是开发高效并发应用程序的关键技术。C++和C语言提供了丰富的接口来实现这一目标,特别是在Linux环境下,可以利用POSIX线程库(pthread)进行多线程编程。本手册专注于讲解如何在Linux系统...

    Linux多线程编程手册,linux多线程编程手册pdf,C,C++源码.zip

    - **线程亲和性**:将线程绑定到特定CPU核心,减少上下文切换。 9. **异常处理** - 在多线程环境中,正确处理异常是非常重要的,确保资源得到正确释放。 通过阅读《Linux多线程编程手册》和分析提供的C/C++源码...

    Java-Thread-Affinity,将Java线程绑定到给定的内核.zip

    Java-Thread-Affinity库填补了这一空白,它允许开发者在Java程序中方便地绑定线程到特定的CPU核心,或者一组核心,以实现更细粒度的控制。 该项目可能包含以下组件和功能: 1. **线程绑定API**:提供了一组API,...

    Linux下的多线程编程方法研究.pdf

    默认情况下,线程是非绑定、非分离的,具有1MB的堆栈空间和与父进程相同的优先级。 在多线程编程中,线程间的同步和互斥是必不可少的部分。其中,互斥锁(mutex)用于保护共享资源,确保同一时间只有一个线程可以...

    Linux 多线程开发技术

    - CPU绑定线程可能导致其他线程无法执行,需要程序员主动释放CPU。 - 并发能力受限于单个进程,不能充分利用多处理器的优势。 - 当一个线程阻塞时,整个进程都会被阻塞。 ##### 内核级线程(Kernel-Level Threads...

    由浅入深Linux下pthread线程库介绍[归类].pdf

    Linux下pthread线程库介绍 本文将详细介绍Linux下pthread线程库的基本概念、线程...被绑定的线程具有较高的响应速度,这是因为CPU时间片的调度是面向轻进程的,绑定的线程可以保证在需要的时候它总有一个轻进程可用。

    由浅入深Linux下pthread线程库介绍

    本文将深入探讨pthread线程库,包括线程的创建与结束、线程绑定、线程状态、线程优先级、线程撤销、线程数据、互斥锁、条件变量、信号量和异步信号等核心概念。 1. 线程创建与结束 - `pthread_t`是线程的标识符,...

    linux下多线程socket通信(完整源码文件)

    在Linux系统中,多线程Socket通信是一种常见的网络编程方式,尤其在服务器开发中,它能够充分利用多核处理器的优势,提高服务的并发处理能力。本文将深入探讨如何在Linux环境下实现多线程Socket通信,结合给出的标题...

    threadBandCpu:将java线程绑定到具体的cpu上执行

    threadBandCpu将java线程绑定到具体的cpu上执行环境:Ubuntu 12.04具体介绍请移步这里:如何使用?调用ThreadBandCpu.bandCpu并实现Runnable的run方法,第二个参数的意思是在第几个cpu上执行假如有4个cpu,那么就是 ...

Global site tag (gtag.js) - Google Analytics