当多个高优先级线程在多个内核上运行时,Linux内核无响应 编写了一个C++多线程的程序,运行10个线程,每个线程设置为高优先级和亲和性。在运行centos 7(Linux内核-3.10.0-229)的具有16个内核的dell计算机上编译并运行此代码,禁用了超线程读取。在我运行了这段代码之后,几秒钟后,我们的Linux机器就没有响应了,从这个意义上说,如果我打开Eclipse编辑器,保存一个文件或在vi编辑器中保存一个文件,这些应用程序就会挂起。有趣的是,一旦我停止这个程序/进程,所有其他应用程序就会从停止的地方恢复。如果我从这10个线程中删除优先级,我也不会看到这个问题
问题:当多个高优先级线程在多个内核上运行时,Linux内核无响应 编写了一个C++多线程的程序,运行10个线程,每个线程设置为高优先级和亲和性。在运行centos 7(Linux内核-3.10.0-229)的具有16个内核的dell计算机上编译并运行此代码,禁用了超线程读取。在我运行了这段代码之后,几秒钟后,我们的Linux机器就没有响应了,从这个意义上说,如果我打开Eclipse编辑器,保存一个文件或在vi编辑器中保存一个文件,这些应用程序就会挂起。有趣的是,一旦我停止这个程序/进程,所有其他应用程序就会从停止的地方恢复。如果我从这10个线程中删除优先级,我也不会看到这个问题,c++,linux,multithreading,C++,Linux,Multithreading,问题: %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 aru
%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, ¶ms);
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
1) 在16个内核中,有6个内核仍然留在机器上(上面的cpu使用率显示,cpu执行了62.9%的用户空间,空闲了37.1%。有趣的是,内核空间的cpu使用率为0%),所以理想情况下内核应该使用这6个内核来处理其他应用程序,其他应用程序无法运行的原因是什么?如何在不引入睡眠/更改优先级的情况下解决此问题
2) 除了在线程中引入睡眠/等待事件(由于内核上下文切换而引入最小延迟)以实现并行性之外,想知道更好的方法吗
运行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, ¶ms);
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
下面的代码:
%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, ¶ms);
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
突然剥夺内核在无限时间内的任何活动内核的使用权的影响是未知的。在获得该内核的独占所有权之前连接到该内核的任何内容(可能包括等待在其上调度的线程)都将永远丢失给系统
别这样 使用高优先级线程进行紧密循环不是一个好主意……当打印hello只是循环而不执行任何操作时,在某些循环之后引入switchtothread/yield,并在较高的循环计数之后休眠零。这将使系统上的其他线程有机会在没有工作时执行并最终等待事件句柄
@kiran0x1B这个问题很有趣,但出于好奇,你为什么要优先运行这些东西?拥有更高优先级的CPU线程正是挂起低优先级程序的诀窍…总是需要CPU的线程应该具有更低的优先级。这台机器有什么CPU?为什么要用GCC/linux指定
-lpthread
?(正确的标志是-pthread
)@MatteoItalia,我正在对我们当前的生产应用程序(多线程)进行优化,它具有类似的体系结构。如果多个使用者线程在数据队列上旋转,而不是在收到通知时等待/唤醒数据,则会获得更好的结果。但是,如果一个核心上有多个消费者线程旋转,我们就会看到上面提到的问题。放弃你的代码,卖掉你的服务器,买一个风扇加热器。这个问题的主要评论区解释了目的(写给Matteo Italia)。CPU这台机器有Intel Xeon CPUI,我建议你弄清楚当线程被唤醒时为什么性能会很差。这很不寻常。只有当队列为空时,线程才应进入睡眠状态;只有当您的性能至少达到您需要的水平时,队列才应为空。此外,“Xeon”是一系列处理器,而不是特定的处理器。我想知道这台机器有哪些特定的处理器。