使用pthread_setschedparam在htop中显示线程的负优先级

时间:2014-12-20 01:17:31

标签: c++ c multithreading c++11 pthreads

我在/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();
       }

1 个答案:

答案 0 :(得分:2)

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在每个进程“stat条目下从名为procfs的文件中获取其信息,例如您的线程信息将从/proc/30010/stat中读取。在manpage for 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的用户可见范围。