1. 程式人生 > >linux執行緒繫結到指定cpu執行

linux執行緒繫結到指定cpu執行

CPU親合力就是指在Linux系統中能夠將一個或多個程序繫結到一個或多個處理器上執行.
一個程序的CPU親合力掩碼決定了該程序將在哪個或哪幾個CPU上執行.在一個多處理器系統中,設定CPU親合力的掩碼可能會獲得更好的效能.
一個CPU的親合力掩碼用一個cpu_set_t結構體來表示一個CPU集合,下面的幾個巨集分別對這個掩碼集進行操作:
   ·CPU_ZERO() 清空一個集合
   ·CPU_SET()與CPU_CLR()分別對將一個給定的CPU號加到一個集合或者從一個集合中去掉.
   ·CPU_ISSET()檢查一個CPU號是否在這個集合中.

下面兩個函式就是用來設定獲取執行緒CPU親和力狀態: 


    ·sched_setaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask) 
      該函式設定程序為pid的這個程序,讓它執行在mask所設定的CPU上.如果pid的值為0,則表示指定的是當前程序,使當前程序執行在mask所設定的那些CPU上.第二個引數cpusetsize是mask所指定的數的長度.通常設定為sizeof(cpu_set_t).如果當前pid所指定的程序此時沒有執行在mask所指定的任意一個CPU上,則該指定的程序會從其它CPU上遷移到mask的指定的一個CPU上執行. 
    ·sched_getaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask) 
      該函式獲得pid所指示的程序的CPU位掩碼,並將該掩碼返回到mask所指向的結構中.即獲得指定pid當前可以執行在哪些CPU上.同樣,如果pid的值為0.也表示的是當前程序

[cpp] view plain copy print?
  1. cpu_set_t的定義  
  2. # define __CPU_SETSIZE 1024
  3. # define __NCPUBITS (8 * sizeof (__cpu_mask))
  4. typedef unsigned longint __cpu_mask;  
  5. # define __CPUELT(cpu) ((cpu) / __NCPUBITS)
  6. # define __CPUMASK(cpu) ((__cpu_mask) 1 << ((cpu) % __NCPUBITS))
  7. typedefstruct
  8. {  
  9. __cpu_mask __bits[__CPU_SETSIZE / __NCPUBITS];  
  10. } cpu_set_t;  
  11. # define __CPU_ZERO(cpusetp) \
  12. do { \  
  13. unsigned int __i; \  
  14. cpu_set_t *__arr = (cpusetp); \  
  15. for (__i = 0; __i < sizeof (cpu_set_t) / sizeof (__cpu_mask); ++__i) \  
  16. __arr->__bits[__i] = 0; \  
  17. while (0)  
  18. # define __CPU_SET(cpu, cpusetp) \
  19. ((cpusetp)->__bits[__CPUELT (cpu)] |= __CPUMASK (cpu))  
  20. # define __CPU_CLR(cpu, cpusetp) \
  21. ((cpusetp)->__bits[__CPUELT (cpu)] &= ~__CPUMASK (cpu))  
  22. # define __CPU_ISSET(cpu, cpusetp) \
  23. (((cpusetp)->__bits[__CPUELT (cpu)] & __CPUMASK (cpu)) != 0)  
cpu_set_t的定義

# define __CPU_SETSIZE 1024
# define __NCPUBITS (8 * sizeof (__cpu_mask))
typedef unsigned long int __cpu_mask;
# define __CPUELT(cpu) ((cpu) / __NCPUBITS)
# define __CPUMASK(cpu) ((__cpu_mask) 1 << ((cpu) % __NCPUBITS))
typedef struct
{
__cpu_mask __bits[__CPU_SETSIZE / __NCPUBITS];
} cpu_set_t;

# define __CPU_ZERO(cpusetp) \
do { \
unsigned int __i; \
cpu_set_t *__arr = (cpusetp); \
for (__i = 0; __i < sizeof (cpu_set_t) / sizeof (__cpu_mask); ++__i) \
__arr->__bits[__i] = 0; \
} while (0)
# define __CPU_SET(cpu, cpusetp) \
((cpusetp)->__bits[__CPUELT (cpu)] |= __CPUMASK (cpu))
# define __CPU_CLR(cpu, cpusetp) \
((cpusetp)->__bits[__CPUELT (cpu)] &= ~__CPUMASK (cpu))
# define __CPU_ISSET(cpu, cpusetp) \
(((cpusetp)->__bits[__CPUELT (cpu)] & __CPUMASK (cpu)) != 0)


 測試程式碼:

[cpp] view plain copy print?
  1. #include<stdlib.h>
  2. #include<stdio.h>
  3. #include<sys/types.h>
  4. #include<sys/sysinfo.h>
  5. #include<unistd.h>
  6. #define __USE_GNU
  7. #include<sched.h>
  8. #include<ctype.h>
  9. #include<string.h>
  10. #include<pthread.h>
  11. #define THREAD_MAX_NUM 100  //1個CPU內的最多程序數
  12. int num=0;  //cpu中核數
  13. void* threadFun(void* arg)  //arg  傳遞執行緒標號(自己定義)
  14. {  
  15.          cpu_set_t mask;  //CPU核的集合
  16.          cpu_set_t get;   //獲取在集合中的CPU
  17.          int *a = (int *)arg;   
  18.          printf("the a is:%d\n",*a);  //顯示是第幾個執行緒
  19.          CPU_ZERO(&mask);    //置空
  20.          CPU_SET(*a,&mask);   //設定親和力值
  21.          if (sched_setaffinity(0, sizeof(mask), &mask) == -1)//設定執行緒CPU親和力
  22.          {  
  23.                    printf("warning: could not set CPU affinity, continuing...\n");  
  24.          }  
  25.          while (1)  
  26.          {  
  27.                    CPU_ZERO(&get);  
  28.                    if (sched_getaffinity(0, sizeof(get), &get) == -1)//獲取執行緒CPU親和力
  29.                    {  
  30.                             printf("warning: cound not get thread affinity, continuing...\n");  
  31.                    }  
  32.                    int i;  
  33.                    for (i = 0; i < num; i++)  
  34.                    {  
  35.                             if (CPU_ISSET(i, &get))//判斷執行緒與哪個CPU有親和力
  36.                             {  
  37.                                      printf("this thread %d is running processor : %d\n", i,i);  
  38.                             }  
  39.                    }  
  40.          }  
  41.          return NULL;  
  42. }  
  43. int main(int argc, char* argv[])  
  44. {  
  45.          num = sysconf(_SC_NPROCESSORS_CONF);  //獲取核數
  46.          pthread_t thread[THREAD_MAX_NUM];  
  47.          printf("system has %i processor(s). \n", num);  
  48.          int tid[THREAD_MAX_NUM];  
  49.          int i;  
  50.          for(i=0;i<num;i++)  
  51.          {  
  52.                    tid[i] = i;  //每個執行緒必須有個tid[i]
  53.                    pthread_create(&thread[0],NULL,threadFun,(void*)&tid[i]);  
  54.          }  
  55.          for(i=0; i< num; i++)  
  56.          {  
  57.                    pthread_join(thread[i],NULL);//等待所有的執行緒結束,執行緒為死迴圈所以CTRL+C結束
  58.          }  
  59.          return 0;  
  60. }  
#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>
#include<pthread.h>
#define THREAD_MAX_NUM 100  //1個CPU內的最多程序數
 
int num=0;  //cpu中核數
void* threadFun(void* arg)  //arg  傳遞執行緒標號(自己定義)
{
         cpu_set_t mask;  //CPU核的集合
         cpu_set_t get;   //獲取在集合中的CPU
         int *a = (int *)arg; 
         printf("the a is:%d\n",*a);  //顯示是第幾個執行緒
         CPU_ZERO(&mask);    //置空
         CPU_SET(*a,&mask);   //設定親和力值
         if (sched_setaffinity(0, sizeof(mask), &mask) == -1)//設定執行緒CPU親和力
         {
                   printf("warning: could not set CPU affinity, continuing...\n");
         }
         while (1)
         {
                   CPU_ZERO(&get);
                   if (sched_getaffinity(0, sizeof(get), &get) == -1)//獲取執行緒CPU親和力
                   {
                            printf("warning: cound not get thread affinity, continuing...\n");
                   }
                   int i;
                   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[])
{
         num = sysconf(_SC_NPROCESSORS_CONF);  //獲取核數
         pthread_t thread[THREAD_MAX_NUM];
         printf("system has %i processor(s). \n", num);
         int tid[THREAD_MAX_NUM];
         int i;
         for(i=0;i<num;i++)
         {
                   tid[i] = i;  //每個執行緒必須有個tid[i]
                   pthread_create(&thread[0],NULL,threadFun,(void*)&tid[i]);
         }
         for(i=0; i< num; i++)
         {
                   pthread_join(thread[i],NULL);//等待所有的執行緒結束,執行緒為死迴圈所以CTRL+C結束
         }
         return 0;
}


編譯命令:gcc bind.c -o bind -lpthread

執行:./bind

輸出結果:略

特別注意:

#define __USE_GNU不要寫成#define _USE_GNU

#include<pthread.h>必須寫在#define __USE_GNU之後,否則編譯會報錯

檢視你的執行緒情況可以在執行時在另一個視窗使用top -H來檢視執行緒的情況,檢視各個核上的情況請使用top命令然後按數字“1”來檢視。


相關推薦

Linux程序或執行CPU+修改優先順序

  轉載自 https://www.cnblogs.com/swey/p/4469722.html 為了讓程式擁有更好的效能,有時候需要將程序或執行緒繫結到特定的CPU,這樣可以減少排程的開銷和保護關鍵程序或執行緒。 程序繫結到CPU Linux提供一個介面,可以

linux執行指定cpu執行

CPU親合力就是指在Linux系統中能夠將一個或多個程序繫結到一個或多個處理器上執行. 一個程序的CPU親合力掩碼決定了該程序將在哪個或哪幾個CPU上執行.在一個多處理器系統中,設定CPU親合力的掩碼可能會獲得更好的效能. 一個CPU的親合力掩碼用一個cpu_

android下將指定的程序/執行指定CPU

針對平臺優化的APP,需要根據具體的CPU型號來將一些任務重,佔CPU資源多的執行緒繫結到CPU上處理能力更強的大核上,可參考如下程式碼: 1、將整個程序中的各個執行緒繫結到指定CPU核 #include <stdio.h> #include <stdlib.h> #

執行CPU

Linux系統提供API函式sched_setaffinity和sched_getaffinity用於設定或獲取執行緒的可以使用的CPU核。 int sched_setaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mas

如何將程序/執行到固定的CPU

#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <pthread.h> #incl

Netty原始碼閱讀之如何將TCP的讀寫操作和指定執行

**原文連結**:[http://xueliang.org/article/detail/20200712234015993](http://xueliang.org/article/detail/20200712234015993) # 前言 在Netty的執行緒模型中,對於一個TCP連線的讀寫操作,都是

ThreadLocal 執行的初識

  遇到多個執行緒訪問同一個變數時使用,類中靜態SimpleDateFormat格式化日期,在一個類中執行緒中使用格式化的類   的格式化方法,用執行緒繫結,來保證同一時間SimpleDateFormat只被一個執行緒使用,不造成因為多執行緒同時使用Sdf出現轉換異常

Hibernate事務操作及session與本地執行

事務相關概念   1 什麼是事務     事務是應用程式中一系列嚴密的操作,所有操作必須成功完成,否則在每個操作中所作的所有更改都會被撤消。也就是事務具有原子性,一個事務中的一系列的操作要麼全部成功,要麼一個都不做。     事務的結束有兩種,當事務中的所以步驟全部成功執行時,事務提交。如果其中

JPA中手動將EntityManager和執行

package com.dimples.service; import javax.persistence.EntityManager; import javax.persistence.Entity

Hibernate中將session與本地執行分析

原文:https://blog.csdn.net/Marvel__Dead/article/details/61654297    為什麼要把Session與本地執行緒繫結? openSession(): 總是建立一個新的session物件 你需要去明確的關閉se

numa的記憶體按節點分配和執行

前段時間在做1.5億條資料的比對, 需要多執行緒和記憶體的訪問問題, 由於記憶體的訪問與numa節點的分配有關,即:cpu訪問本地節點的記憶體速度要快。 現將numa的幾個庫函式做一下說明: int main() { if(numa_available()<0)

Linux系統下編寫shell指令碼傳入引數列印系統當前執行數到指定檔案

  最近在做效能測試,要檢視系統執行過程中執行緒數,很簡單輸入命令:netstat -anp |grep java |wc -l,可以查詢。但是如何在執行過程定時列印系統執行緒數且將結果輸出到指定檔案呢?也很簡單我們直接寫一個shell指令碼執行下就可以了。以

Linux指定CPU執行程式指令碼

#!/bin/sh for pid in `ps -e|grep ora|awk '{print $1}'`; do taskset -pc 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 $pid; done

linux之通過ptrace獲取指定pthread執行的暫存器資訊

#include <stdio.h> #include <unistd.h> //for sleep #include <stdlib.h> //for exit

Netty服務端接收的新連線是如何到worker執行池的?

  更多技術分享可關注我 前言 原文:Netty服務端接收的新連線是如何繫結到worker執行緒池的? 前面分析Netty服務端檢測新連線的過程提到了NioServerSocketChannel讀完新連線後會迴圈呼叫服務端Channel繫結的pipeline.fireChannelRead()方

linux執行基礎概念及多執行程式設計

Linux中執行緒的概念: 首先,Linux中並不存在真在的執行緒。Linux中的執行緒是使用程序來模擬的。在一個程序需要同時執行多個執行流時,linux並不是開闢多個執行緒來執行,而是通過多個程序來模擬多個執行緒。 Linux中執行緒的實現原理: 首先先看一下張圖: 此時共有

Linux的Apache應用筆記--指定地址與埠

配置Apache HTTP伺服器來監聽特定的地址和埠 概述 Listen: 監聽指定的埠或主機地址或者兩者的組合,這決定了httpd如何響應不同的ip地址、主機名和埠。 為了讓主機響應埠8

對於多執行程式,單核cpu與多核cpu是怎麼工作的

此文中的大部分資料來自於網路上,我只是覺得把有道理的整理一下,方便以後查閱。 1.多執行緒在單核和多核CPU上的執行效率問題的討論a1: 多執行緒在單cpu中其實也是順序執行的,不過系統可以幫你切換那個執行而已,其實並沒有快(反而慢)多個cpu的話就可以在兩個cpu中同時執行了.....

Linux執行相關API及基礎執行

多執行緒:由程序生成,資源是程序給的,共享主執行緒資源,程序退出了,執行緒就沒有了                 1、執行緒的建立                     #include <pthread.h>                     int

Linux執行實踐(四 )執行的特定資料

在單執行緒程式中,我們經常要用到"全域性變數"以實現多個函式間共享資料, 然而在多執行緒環境下,由於資料空間是共享的,因此全域性變數也為所有執行緒所共有。但有時應用程式設計中有必要提供執行緒私有的全域