当多个高优先级线程在多个核上运行时,Linux内核无响应

时间:2015-11-04 22:43:16

标签: c++ linux multithreading

编写了一个示例C ++多线程程序,该程序运行10个线程,每个线程设置为高优先级和亲和性。在dell机器上编译并运行此代码,该机器具有16个内核,运行centos 7(Linux内核 - 3.10.0-229),禁用超线程。在我运行此代码后,几秒钟内,我们的Linux机器变得没有响应,从某种意义上说,如果我打开Eclipse编辑器,保存文件或在vi编辑器中保存文件,那些应用程序就会挂起。有趣的是,一旦我停止了这个程序/过程,那么所有其他应用程序将从他们停止的地方恢复。如果我从这10个线程中删除优先级,我也不会看到这个问题。

问题

1)在16个内核中,6个内核仍留在机器上(cpu使用率显示,cpu执行62.9%的用户空间,空闲时占37.1%。有趣的是内核空间中0%的cpu使用率),所以理想情况下内核应该使用这6个内核来处理其他应用程序,这可能是其他应用程序无法运行的原因?如何在不引入睡眠/更改优先级的情况下解决此问题?

2)除了在线程中引入睡眠/等待事件(由于内核上下文切换引入最小延迟)以实现并行性之外,想知道更好的方法吗?

Ran top命令(top -H

%Cpu(s):  62.9 us,  0.0 sy,  0.0 ni, 37.1 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st

1107 arun      rt   0   96748   1112    932 R 99.9  0.0   0:25.78 PthreadTest
1115 arun      rt   0   96748   1112    932 R 99.9  0.0   0:24.79 PthreadTest
1118 arun      rt   0   96748   1112    932 R 99.9  0.0   0:22.79 PthreadTest
1120 arun      rt   0   96748   1112    932 R 99.9  0.0   0:20.79 PthreadTest
1123 arun      rt   0   96748   1112    932 R 99.9  0.0   0:18.79 PthreadTest
1117 arun      rt   0   96748   1112    932 R 94.1  0.0   0:23.78 PthreadTest
1119 arun      rt   0   96748   1112    932 R 94.1  0.0   0:21.78 PthreadTest
1122 arun      rt   0   96748   1112    932 R 94.1  0.0   0:19.78 PthreadTest
1124 arun      rt   0   96748   1112    932 R 94.1  0.0   0:17.78 PthreadTest
1125 arun      rt   0   96748   1112    932 R 94.1  0.0   0:16.76 PthreadTest

以下代码

#include <unistd.h>
#include <iostream>
#include <cstdlib>
#include <pthread.h>

using namespace std;

#define NUM_THREADS 10

void *PrintHello(void *threadid)
{
   long tid;
   tid = (long)threadid;

   cout << "Hello World! Thread ID, " << tid << endl;
   while(true)
   {
        continue;
   }
   pthread_exit(NULL);
}

int main ()
{
   pthread_t threads[NUM_THREADS];
   pthread_attr_t  threads_attr[NUM_THREADS];
   struct sched_param     params;
   params.sched_priority = sched_get_priority_max(SCHED_FIFO);
   int rc;
   int i;
   int cpu_num = 0;

   for( i=0; i < NUM_THREADS; i++ ){

      cpu_set_t cpu;
      CPU_ZERO(&cpu);
      CPU_SET(cpu_num, &cpu);
      cout << "main() : creating thread, " << i << "cpu_num : "<<cpu_num<<endl;
      pthread_attr_init(&threads_attr[i]);
      pthread_attr_setscope(&threads_attr[i], PTHREAD_SCOPE_SYSTEM);
      rc = pthread_create(&threads[i], NULL,
                          PrintHello, (void *)i);
      if (rc){
         cout << "Error:unable to create thread," << rc << endl;
         exit(-1);
      }

      sleep(1);


      int ret = pthread_setaffinity_np(threads[i], sizeof(cpu_set_t), &cpu);
      if(ret == 0 && CPU_ISSET(cpu_num, &cpu))
      {
        cout << "Thread " << i << " affinity set " <<endl;
      }


      ret = pthread_setschedparam(threads[i], SCHED_FIFO, &params);
      if(ret == 0)
      {
        cout << "Thread " << i << " priority set " <<endl;
      }
      cpu_num++;
   }


// free attribute and wait for the other threads
   void *status;
   for( i=0; i < NUM_THREADS; i++ )
   {
        rc = pthread_join(threads[i], &status);
        if (rc){
            cout << "Error:unable to join," << rc << endl;
            exit(-1);
        }
        cout << "Main: completed thread id :" << i ;
        cout << "  exiting with status :" << status << endl;
   }

   pthread_exit(NULL);
}

编译

g++ -std=c++14 -g -o PthreadTest busywait.cpp -lpthread

2 个答案:

答案 0 :(得分:1)

突然剥夺内核在无限时间内使用活核心的影响尚未明确且未知。在对其进行独占所有权之前附加到该核心的任何内容(可能包括等待在其上进行调度的线程)将永远丢失到系统中。

不要这样做!

答案 1 :(得分:-1)

具有高优先级线程的紧密循环不是一个好主意...当打印问候语只是循环而没有做任何事情时,在某些循环之后引入switchtothread / yield并在更高的循环计数之后隐藏零。这将使系统上的其他线程实现最终执行。当没有工作时,最终等待事件句柄。

@ kiran0x1B