最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Linux下進(jìn)程的CPU配置與線程綁定過程

 更新時(shí)間:2025年07月11日 15:15:54   作者:比特熊貓  
本文介紹Linux系統(tǒng)中基于進(jìn)程和線程的CPU配置方法,通過taskset命令和pthread庫調(diào)整親和力,將進(jìn)程/線程綁定到特定CPU核心以優(yōu)化資源分配,提升系統(tǒng)性能與實(shí)時(shí)任務(wù)響應(yīng)效率,同時(shí)強(qiáng)調(diào)操作驗(yàn)證及注意事項(xiàng)

1 基于進(jìn)程的CPU配置

基于進(jìn)程的CPU配置技術(shù)是指在Linux操作系統(tǒng)中,通過調(diào)整進(jìn)程的CPU使用率來實(shí)現(xiàn)對系統(tǒng)資源的合理分配和管理。這種技術(shù)可以用于限制特定進(jìn)程的CPU使用,防止其占用過多的CPU資源,從而保證系統(tǒng)的穩(wěn)定性和性能。

基于進(jìn)程的CPU配置是指將一個(gè)進(jìn)程綁定到特定的CPU核心或者CPU集合上運(yùn)行。這樣可以控制進(jìn)程在特定的CPU資源上執(zhí)行,以提高性能或?qū)崿F(xiàn)特定的調(diào)度策略。

1.1 對CPU親和力的配置

對于CentOS 8下的Linux系統(tǒng),首先可以使用top命令來查看當(dāng)前的CPU占用率,如下圖所示:

鍵盤上按數(shù)字1,可以以數(shù)據(jù)化的形式看到具體的使用情況,如下圖:

鍵盤上按字母t,可以以圖形化的形式看到具體的使用情況,如下圖:

可以看到,當(dāng)前的CPU基本是空閑的狀態(tài)。

這時(shí)候,我們寫一個(gè)測試代碼,讓其掛在后臺(tái)運(yùn)行,例如下面的一個(gè)死循環(huán)函數(shù):

#include <iostream>

int main()
{
    while (true) {
        // 在這里編寫你的代碼
        // 例如,輸出一條信息
        std::cout << "Hello, I am running in an infinite loop!" << std::endl;
    }

    return 0;
}

讓其掛在后臺(tái)運(yùn)行著,暫時(shí)不管。

如下圖:

此時(shí),我們再次使用top命令,來查看當(dāng)前的CPU 狀態(tài),如下圖:

可以看到,此時(shí)循環(huán)代碼這個(gè)進(jìn)程正在后臺(tái)不停運(yùn)行,此時(shí)的CPU占用率相比開始,非常的高。

記住當(dāng)前的進(jìn)程PID,然后使用taskset -c -p 13265 命令查看當(dāng)前進(jìn)程的CPU親和力。13265是當(dāng)前進(jìn)程的PID。

可以從輸出的信息看出,pid 為13265的進(jìn)程(即當(dāng)前的測試進(jìn)程)的親和力CPU為0-3,即它同時(shí)運(yùn)行在了0,1,2,3這四個(gè)CPU上面。

現(xiàn)在我們更改pid 為13265的進(jìn)程(即當(dāng)前的測試進(jìn)程)的親和力,將其改成只在0,1這兩個(gè)CPU上面運(yùn)行。如下圖:

這里由于我使用了ctrl + c暫停了剛才的進(jìn)程,然后重新啟動(dòng)該進(jìn)程時(shí),進(jìn)程的PID變成了13495,不過這沒有任何影響??梢钥吹?,當(dāng)前的進(jìn)程新的親和力列表為0,1,說明設(shè)置新的CPU親和力成功。而pid 13495 的當(dāng)前親和力掩碼為3,同樣能說明親和力設(shè)置成功。使用taskset命令來查看進(jìn)程運(yùn)行在哪個(gè)CPU上。

使用以下命令:

taskset -p < PID >

【請將< PID >替換為你要查看的進(jìn)程的實(shí)際PID?!?/p>

該命令將顯示進(jìn)程的當(dāng)前親和力掩碼,其中每個(gè)位表示一個(gè)CPU核心。例如,如果輸出為pid 's current affinity mask: 3,表示進(jìn)程當(dāng)前在CPU核心0和1上運(yùn)行,因?yàn)槎M(jìn)制表示為11。

再次實(shí)驗(yàn)一下,這次我們將CPU親和力設(shè)置在CPU 1,CPU2上,如下圖:

由當(dāng)前親和力掩碼可以看到,為6,說明此時(shí)運(yùn)行在CPU1和CPU2上。(2^1 + 2^2 = 6)

1.2 綁定進(jìn)程到指定CPU核上運(yùn)行

查看CPU有幾個(gè)核

使用 cat /proc/cpuinfo 查看CPU信息,如下兩個(gè)信息:

  • ·processor:指明第幾個(gè)cpu處理器
  • ·cpu cores:指明每個(gè)處理器的核心數(shù)

以本機(jī)中虛擬機(jī)為例,有4個(gè)CPU(分別為:CPU0, CPU1, CPU2, CPU3),每個(gè)CPU有1個(gè)核。

也可以使用系統(tǒng)調(diào)用sysconf獲取CPU核心數(shù):

#include <unistd.h>

int sysconf(_SC_NPROCESSORS_CONF);/* 返回系統(tǒng)可以使用的核數(shù),但是其值會(huì)包括系統(tǒng)中禁用的核的數(shù)目,因 此該值并不代表當(dāng)前系統(tǒng)中可用的核數(shù) */
int sysconf(_SC_NPROCESSORS_ONLN);/* 返回值真正的代表了系統(tǒng)當(dāng)前可用的核數(shù) */

/* 以下兩個(gè)函數(shù)與上述類似 */
#include <sys/sysinfo.h>

int get_nprocs_conf (void);/* 可用核數(shù) */
int get_nprocs (void);/* 真正的反映了當(dāng)前可用核數(shù) */

使用 taskset 指令 

  • 獲取進(jìn)程pid:

  • 查看進(jìn)程當(dāng)前運(yùn)行在哪個(gè)CPU上:

顯示的十六進(jìn)制f轉(zhuǎn)換為二進(jìn)制為最低四個(gè)是1,每個(gè)1對應(yīng)一個(gè)CPU,所以進(jìn)程運(yùn)行在4個(gè)CPU上。

  • 指定進(jìn)程10770運(yùn)行在CPU0上:

注意,CPU的標(biāo)號(hào)是從0開始的,所以cpu0表示第1個(gè)CPU(第一個(gè)CPU的標(biāo)號(hào)是0)。

至此,就把應(yīng)用程序綁定到了CPU0上運(yùn)行,查看如下:

  • 啟動(dòng)程序時(shí)綁定CPU:

例如啟動(dòng)時(shí)綁定到第二個(gè)CPU上,即CPU1:

使用sched_setaffinity系統(tǒng)調(diào)用 

通過系統(tǒng)調(diào)用sched_setaffinity進(jìn)行綁定,通過sched_getaffinity獲取綁定關(guān)系。注意這對方法是進(jìn)程級別的綁定。代碼中指定cpu0和cpu3,我們可以通過top查看,兩個(gè)CPU使用達(dá)到了100%,其他的CPU均不會(huì)(正常場景)。

sched_setaffinity可以將某個(gè)進(jìn)程綁定到一個(gè)特定的CPU。
#define _GNU_SOURCE             /* See feature_test_macros(7) */
#include <sched.h>

/* 設(shè)置進(jìn)程號(hào)為pid的進(jìn)程運(yùn)行在mask所設(shè)定的CPU上
 * 第二個(gè)參數(shù)cpusetsize是mask所指定的數(shù)的長度
 * 通常設(shè)定為sizeof(cpu_set_t)

 * 如果pid的值為0,則表示指定的是當(dāng)前進(jìn)程 
 */
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所指示的進(jìn)程的CPU位掩碼,并將該掩碼返回到mask所指向的結(jié)構(gòu)中 */

代碼示例:

/*

*該程序演示了如何使用sched_setaffinity函數(shù)將線程綁定到特定的CPU核心上運(yùn)行。
*程序首先創(chuàng)建了兩個(gè)線程,然后使用sched_setaffinity函數(shù)將線程1綁定到CPU 0上,將線程2綁定到CPU 3上。
*運(yùn)行時(shí),可以通過查看輸出的pid來確定程序的進(jìn)程ID。
*然后,程序?qū)PU_ZERO宏應(yīng)用于一個(gè)cpu_set_t類型的變量mask,以將其初始化為空集。
*接下來,程序?qū)PU_SET宏應(yīng)用于mask,將CPU 0和CPU 3添加到集合中。
*最后,程序調(diào)用sched_setaffinity函數(shù)將mask應(yīng)用于當(dāng)前進(jìn)程,將線程1綁定到CPU 0上,將線程2綁定到CPU 3上。
*線程創(chuàng)建成功后,程序使用pthread_join函數(shù)等待線程1和線程2的結(jié)束。
*/
#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; // 定義cpu_set_t類型的變量mask,用于存儲(chǔ)CPU集合
  printf("pid=%d\n", getpid()); // 打印進(jìn)程ID
  CPU_ZERO(&mask); // 將mask初始化為空集
  CPU_SET(0, &mask);//將cpu0綁定到mask中
  CPU_SET(3, &mask);//將cpu3綁定到mask中

  // 將mask應(yīng)用于當(dāng)前進(jìn)程,綁定線程到指定的CPU核心
  sched_setaffinity(0, sizeof(cpu_set_t), &mask) ;
  
  pthread_t tid1;//創(chuàng)建線程1
  if (pthread_create(&tid1, NULL, (void *)testfunc, NULL) != 0) 
  {      
    fprintf(stderr, "thread create failed\n"); // 線程創(chuàng)建失敗,打印錯(cuò)誤信息
    return -1;   
  }
  pthread_t tid2;//創(chuàng)建線程2
  if (pthread_create(&tid2, NULL, (void *)testfunc, NULL) != 0) 
  {      
    fprintf(stderr, "thread create failed\n"); // 線程創(chuàng)建失敗,打印錯(cuò)誤信息
    return -1;   
  } 
  pthread_join(tid1, NULL); // 等待線程1結(jié)束
  pthread_join(tid1, NULL); // 等待線程2結(jié)束
  return 0;
}

執(zhí)行結(jié)果如下圖所示: 

  • 執(zhí)行前:

  • 執(zhí)行后:

2 基于線程的CPU配置

2.1 線程綁定:使用函數(shù)pthread_setaffinity_np

線程綁定CPU核心的意義:

  • 在多核CPU中合理的調(diào)度線程在各個(gè)核上運(yùn)行可以獲得更高的性能。
  • 在多線程編程中,每個(gè)線程處理的任務(wù)優(yōu)先級是不一樣的,對于要求實(shí)時(shí)性比較高的線程或者是主線程,對于這種線程我們可以在創(chuàng)建線程時(shí)指定其綁定到某個(gè)CPU核上,以后這個(gè)核就專門處理該線程。
  • 這樣可以使得該線程的任務(wù)可以得到較快的處理,特別是和用戶直接交互的任務(wù),較短的響應(yīng)時(shí)間可以提升用戶的體驗(yàn)感。

幾個(gè)重要的宏操作:

一個(gè)線程的CPU親合力掩碼用一個(gè)cpu_set_t結(jié)構(gòu)體來表示一個(gè)CPU集合,下面的幾個(gè)宏分別對這個(gè)掩碼集進(jìn)行操作:

CPU_ZERO() 清空一個(gè)集合
CPU_SET()與CPU_CLR()分別對將一個(gè)給定的CPU號(hào)加到一個(gè)集合或者從一個(gè)集合中去掉
CPU_ISSET()檢查一個(gè)CPU號(hào)是否在這個(gè)集合中

設(shè)置獲取線程CPU親和力狀態(tài):

sched_setaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask)

該函數(shù)設(shè)置線程為pid的這個(gè)線程,讓它運(yùn)行在mask所設(shè)定的CPU上。

如果pid的值為0,則表示指定的是當(dāng)前線程,使當(dāng)前線程運(yùn)行在mask所設(shè)定的那些CPU上。

第二個(gè)參數(shù)cpusetsize是mask所指定的數(shù)的長度。通常設(shè)定為sizeof(cpu_set_t)。

如果當(dāng)前pid所指定的線程此時(shí)沒有運(yùn)行在mask所指定的任意一個(gè)CPU上,則該指定的線程會(huì)從其它CPU上遷移到mask的指定的一個(gè)CPU上運(yùn)行。

sched_getaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask)

該函數(shù)獲得pid所指示的線程的CPU位掩碼,并將該掩碼返回到mask所指向的結(jié)構(gòu)中。即獲得指定pid當(dāng)前可以運(yùn)行在哪些CPU上。同樣,如果pid的值為0。也表示的是當(dāng)前進(jìn)程。

簡單的實(shí)例:

// 此代碼不完整,只是幫助理解綁定過程
// 在創(chuàng)建線程時(shí)添加以下代碼,可以將該線程綁定到1核
cpu_set_t mask;

// 將掩碼清零
CPU_ZERO(&mask);

// 將1添加到掩碼中
CPU_SET(1, &mask);

// #將本線程綁定到1核
sched_setaffinity(0, sizeof(cpu_set_t), &mask);

查看線程是否運(yùn)行在指定的核上:

實(shí)際工作中,為了方便查看線程的情況,會(huì)在創(chuàng)建線程時(shí)將相關(guān)信息保存到一個(gè)文件中,需要時(shí)用cat命令查看,內(nèi)容包括創(chuàng)建了哪些線程、線程名稱、線程id和pid、綁定的CPU核、優(yōu)先級、調(diào)度方式等。

使用“top”命令查看:

  • top -d 2:查看線程的運(yùn)行情況和CPU狀態(tài)
  • 按’h’ 和 1:在上一句的基礎(chǔ)上可以查看更詳細(xì)的信息。

從文件中得到線程pid和ppid,通過top命令,查看線程在哪個(gè)CPU核上運(yùn)行,驗(yàn)證核綁定的核是否一樣。

對于線程綁定,我們需要借助pthread庫,通過函數(shù)pthread_setaffinity_np來設(shè)置綁定cpu關(guān)系。我們通過top查看,會(huì)發(fā)現(xiàn)cpu0和cpu3使用率達(dá)到100%。

代碼實(shí)例:

/*
 *該程序演示了如何使用pthread_setaffinity_np函數(shù)將線程綁定到特定的CPU核心上運(yùn)行。
 *程序首先創(chuàng)建了兩個(gè)線程,然后使用pthread_setaffinity_np函數(shù)將線程1綁定到CPU 0上,將線程2綁定到CPU 3上。
 *運(yùn)行時(shí),可以通過查看輸出的pid來確定程序的進(jìn)程ID。
 *然后,程序?qū)PU_ZERO宏應(yīng)用于一個(gè)cpu_set_t類型的變量mask,以將其初始化為空集。
 *接下來,程序使用pthread_create函數(shù)創(chuàng)建線程1和線程2,并檢查線程創(chuàng)建是否成功。
 *然后,程序打印出線程1和線程2的ID。
 *程序使用CPU_SET宏將CPU 0添加到mask中,并使用pthread_setaffinity_np函數(shù)將mask應(yīng)用于線程1,將線程1綁定到CPU 0上。
 *然后,程序清除之前設(shè)置的mask,并將CPU 3添加到mask中,并使用pthread_setaffinity_np函數(shù)將mask應(yīng)用于線程2,將線程2綁定到CPU   3上。
 *最后,程序使用pthread_join函數(shù)等待線程1和線程2的結(jié)束。
*/
#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; // 初始化循環(huán)計(jì)數(shù)器為3
  while(i) { // 進(jìn)入循環(huán),條件為i非零
     sleep(5); // 休眠5秒
     printf("tid=%d,cpu=%d\n",pthread_self(), sched_getcpu()); // 打印線程ID和CPU編號(hào)
     i--; // 計(jì)數(shù)器減一
  }
  while(1); // 進(jìn)入無限循環(huán)
  return NULL; 
}

int main()
{
  cpu_set_t mask; // 定義CPU集合
  printf("pid=%d\n", getpid()); // 打印進(jìn)程ID
  CPU_ZERO(&mask); // 清空CPU集合
  
  pthread_t tid1; // 定義線程tid1
  if (pthread_create(&tid1, NULL, (void *)testfunc, NULL) != 0) 
  {      
    fprintf(stderr, "thread create failed\n"); // 線程創(chuàng)建失敗,打印錯(cuò)誤信息
    return -1;   
  }
  pthread_t tid2; // 定義線程tid2
  if (pthread_create(&tid2, NULL, (void *)testfunc, NULL) != 0) 
  {      
    fprintf(stderr, "thread create failed\n"); // 線程創(chuàng)建失敗,打印錯(cuò)誤信息
    return -1;   
  } 
  printf("tid1=%d,tid2=%d\n", tid1,tid2); // 打印線程tid1和tid2的值
 
  CPU_SET(0, &mask); // 將CPU0加入CPU集合
  pthread_setaffinity_np(tid1, sizeof(cpu_set_t), &mask) ; // 設(shè)置線程tid1的CPU親和性為CPU0
  
  // 清除之前設(shè)置,重新設(shè)置綁定cpu3
  CPU_ZERO(&mask); // 清空CPU集合
  CPU_SET(3, &mask); // 將CPU3加入CPU集合
  pthread_setaffinity_np(tid2, sizeof(cpu_set_t), &mask) ; // 設(shè)置線程tid2的CPU親和性為CPU3
  
  pthread_join(tid1, NULL); // 等待線程tid1結(jié)束
  pthread_join(tid1, NULL); // 等待線程tid2結(jié)束
  return 0;
}
  • 執(zhí)行之后:

  • 將其kill,恢復(fù):

建議:進(jìn)行配置之前先將虛擬機(jī)拍攝快照,以防配置不當(dāng)出現(xiàn)意外情況。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Ubuntu Apahce2.4下無法訪問JS目錄的問題解決

    Ubuntu Apahce2.4下無法訪問JS目錄的問題解決

    這篇文章主要給大家介紹了如何解決Ubuntu Apahce2.4下無法訪問JS目錄的問題,文中介紹的非常詳細(xì),相信對大家具有一定的參考價(jià)值,需要的朋友們下面來一起看看吧。
    2017-03-03
  • Ubuntu系統(tǒng)中查看網(wǎng)絡(luò)速率的幾種方法

    Ubuntu系統(tǒng)中查看網(wǎng)絡(luò)速率的幾種方法

    這篇文章主要給大家介紹了在 Ubuntu系統(tǒng)中,可以使用以下幾種方法查看網(wǎng)絡(luò)速率,文中通過代碼示例講解的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-11-11
  • Ubuntu14.04服務(wù)器環(huán)境下配置PHP7.0+Apache2+Mysql5.7的方法

    Ubuntu14.04服務(wù)器環(huán)境下配置PHP7.0+Apache2+Mysql5.7的方法

    這篇文章主要介紹了Ubuntu14.04服務(wù)器環(huán)境下配置PHP7.0+Apache2+Mysql5.7的方法,較為詳細(xì)的分析了Ubuntu14.04操作系統(tǒng)環(huán)境下配置PHP7.0+Apache2+Mysql5.7的具體步驟與相關(guān)命令使用技巧,需要的朋友可以參考下
    2018-04-04
  • Ubuntu16.04搭建NFS 文件共享服務(wù)器的方法

    Ubuntu16.04搭建NFS 文件共享服務(wù)器的方法

    這篇文章主要介紹了Ubuntu16.04搭建NFS 文件共享服務(wù)器的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-04-04
  • Linux sudo 漏洞可能導(dǎo)致未經(jīng)授權(quán)的特權(quán)訪問

    Linux sudo 漏洞可能導(dǎo)致未經(jīng)授權(quán)的特權(quán)訪問

    sudo 命令中最近發(fā)現(xiàn)了一個(gè)嚴(yán)重漏洞,如果被利用,普通用戶可以 root 身份運(yùn)行命令,在 Linux 中利用新發(fā)現(xiàn)的 sudo 漏洞可以使某些用戶以 root 身份運(yùn)行命令,感興趣的朋友跟隨小編一起看看吧
    2019-10-10
  • 詳解Apache SkyWalking 告警配置指南

    詳解Apache SkyWalking 告警配置指南

    這篇文章主要介紹了Apache SkyWalking 告警配置指南,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • 使用Apache?Camel表達(dá)REST服務(wù)的方法

    使用Apache?Camel表達(dá)REST服務(wù)的方法

    Apache Camel可以作為一個(gè)獨(dú)立的或嵌入的庫在任何地方運(yùn)行,它可以幫助整合,這篇文章主要介紹了如何使用Apache?Camel表達(dá)REST服務(wù),需要的朋友可以參考下
    2022-06-06
  • CentOS安裝Maven實(shí)踐

    CentOS安裝Maven實(shí)踐

    文章詳細(xì)介紹了在CentOS系統(tǒng)上安裝配置Maven的步驟:檢查Java環(huán)境、下載解壓Maven、設(shè)置環(huán)境變量與本地倉庫、配置阿里云鏡像加速,并提供常見問題解決方案及驗(yàn)證方法,確保Maven正確安裝與使用
    2025-09-09
  • Centos Linux7設(shè)置靜態(tài)IP的實(shí)例

    Centos Linux7設(shè)置靜態(tài)IP的實(shí)例

    這篇文章主要介紹了Centos Linux7設(shè)置靜態(tài)IP的實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • Apache開啟并實(shí)現(xiàn)網(wǎng)站偽靜態(tài)化的方法

    Apache開啟并實(shí)現(xiàn)網(wǎng)站偽靜態(tài)化的方法

    Apache的Mod_Rewrite對URL進(jìn)行重寫,實(shí)現(xiàn)網(wǎng)站偽靜態(tài)化,這里就為大家介紹一下
    2022-08-08

最新評論

周至县| 二手房| 靖边县| 吉安县| 大庆市| 抚宁县| 咸丰县| 科技| 旌德县| 大宁县| 庆安县| 柳江县| 宁武县| 靖宇县| 偃师市| 广汉市| 巴青县| 雷山县| 舞阳县| 长沙县| 郓城县| 平南县| 宜章县| 射阳县| 阜新市| 彩票| 湘潭县| 新郑市| 陵川县| 搜索| 阿图什市| 屯留县| 囊谦县| 汝州市| 明光市| 迁西县| 莱西市| 舞阳县| 灵台县| 河池市| 安国市|