簡體   English   中英

使用pthread_setschedparam在htop中顯示線程的負優先級

[英]using pthread_setschedparam shows negative priorities on threads in htop

我在/etc/security/limits.conf中的centOS版本6.5內核3.4.102-1 x86_64的自定義構建中設置了以下內容

*             -       rtprio          99 

當我運行下面的代碼以獲得名為PThreadAffinity的測試代碼時,下面顯示了進程和優先級的線程(向右滾動以查看樹)。 為什么優先級沒有按照代碼中的規定顯示? 這意味着分配給main()中下面的線程的優先級是39,1,20和2.雖然在htop中它們顯示為-3,-21,-2和-40。

30009 bjackfly   20   0  303M  1036   864 S  0.0  0.0  0:00.00 │  │        └─ ./PThreadAffinity     
30013 bjackfly   -3   0  303M  1036   864 S  0.0  0.0  0:00.00 │  │           ├─ ./PThreadAffinity  
30012 bjackfly  -21   0  303M  1036   864 S  0.0  0.0  0:00.00 │  │           ├─ ./PThreadAffinity  
30011 bjackfly   -2   0  303M  1036   864 S  0.0  0.0  0:00.00 │  │           ├─ ./PThreadAffinity  
30010 bjackfly  -40   0  303M  1036   864 S  0.0  0.0  0:00.00 │  │           └─ ./PThreadAffinity  

消息來源:

       #include <thread>
       #include <pthread.h>
       #include <sstream>
       #include <cstring>
       #include <iostream>
       #include <stdexcept>

       std::string schedAttrAsStr(const int aPolicy, const sched_param &aParam) {
           std::stringstream ss;
           ss << ((aPolicy == SCHED_FIFO)  ? "SCHED_FIFO" :
                   (aPolicy == SCHED_RR)    ? "SCHED_RR" :
                   (aPolicy == SCHED_OTHER) ? "SCHED_OTHER" :
                   "???")
               << " @ " << aParam.sched_priority;
           return ss.str();
       }

       void createManaged(std::string aName, int aCpuNum, int aPriority, int aPolicy) { 
           cpu_set_t cpus;
           CPU_ZERO(&cpus);
           CPU_SET(aCpuNum, &cpus);
           int err;
           if((err = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpus)) != 0)  {
               std::ostringstream os;
               os << "ERROR: Could not set affinity for cpu " << aCpuNum << "\n";
               std::cout << os.str() << std::endl;
           }

           // check if we have an exsiting schedule parameter
           sched_param oldParam;
           int oldPolicy;
           if(pthread_getschedparam(pthread_self(), &oldPolicy, &oldParam) == 0) {
               std::ostringstream os;
               os << "Threader old param for " << aName << " is " << schedAttrAsStr(oldPolicy, oldParam) << "\n"; 
           }


           sched_param param;
           memset(&param,0,sizeof(param));
           param.sched_priority = aPriority;
           if (aPriority > sched_get_priority_max(aPolicy)  || aPriority < sched_get_priority_min(aPolicy) ) { 
               std::ostringstream os;
               os << "Priority: " << aPriority << " is out of range for Policy: " << schedAttrAsStr(aPolicy, param)  << "\n";
               std::cout << os.str() << std::endl;
               throw std::runtime_error(os.str().c_str());
           }

           int ret = pthread_setschedparam(pthread_self(), aPolicy, &param);
           if(ret != 0) { 
               std::ostringstream os;
               std::cout << " Failed to set scheduler parameters for: " << aName << "\n";
               os << os.str() << std::endl;
               throw std::runtime_error(os.str().c_str());
           }
           else 
           {
               std::ostringstream os;
               os  << "Threader successfully set scheduler parameters for " << aName << " thread to " << schedAttrAsStr(aPolicy, param) <<
   "\n";
               std::cout << os.str() << std::endl;;
           }

           // Verify new
           if(pthread_getschedparam(pthread_self(), &oldPolicy, &oldParam) == 0)  { 
               std::ostringstream os;
               os << "Threader new param for " << aName << " is " << schedAttrAsStr(oldPolicy, oldParam) << "\n";
               std::cout << os.str() << std::endl;
           }
           else { 
               std::ostringstream os;
               os << " Threader Failed to get new parameters for: " << aName << "\n";
               std::cout << os.str() << std::endl;
           }
       };

       void runData(int aThreshold, std::string aName, int aCpuNum, int aPriority, int aPolicy) { 
           createManaged(aName,aCpuNum,aPriority,aPolicy);
           std::chrono::milliseconds timespan(aThreshold);      
           std::this_thread::sleep_for(timespan);

           std::ostringstream os;
           os << "Done Processing ThreadID: " << std::this_thread::get_id() << "\n";
           std::cout << os.str() << std::endl;
       }

       int main() { 
           std::thread thr1(runData,900000,"Thread1",1,39,SCHED_FIFO);
           std::thread thr2(runData,900000,"Thread2",2,1,SCHED_FIFO);
           std::thread thr3(runData,900000,"Thread3",3,20,SCHED_FIFO);
           std::thread thr4(runData,900000,"Thread4",4,2,SCHED_FIFO);

           thr1.join();
           thr2.join();
           thr3.join();
           thr4.join();
       }

tl; dr - procfs將實時優先級報告為1- prio ,但您的代碼實際上正常工作。

這主要是因為/proc文件系統的復雜性。

首先,您將向后映射優先級(查看htop輸出中的進程ID)。 真實的映射如下:

Thread1: Prio 39, reported -40
Thread2: Prio 1 , reported -2
Thread3: Prio 20, reported -21
Thread4: Prio 2 , reported -3

htop從每個進程' procfs條目下的stat文件中獲取其信息,例如,您的線程信息將從/proc/30010/stat讀取。 procfs聯機幫助頁面如下:

/ proc / [pid] / stat有關進程的狀態信息。 這由ps(1)使用。 它在/usr/src/linux/fs/proc/array.c中定義。

...

(18)(Linux 2.6的說明)對於運行實時調度策略的進程(下面的策略;參見sched_setscheduler(2)),這是否定的調度優先級,減1; 也就是說,-2到-100范圍內的數字,對應於實時優先級1到99.對於在非實時調度策略下運行的進程,這是原始的nice值(setpriority(2))as在內核中表示。 內核將好的值存儲為0(高)到39(低)范圍內的數字,對應於-20到19的用戶可見的良好范圍。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM