写了一个运行10个线程的示例C ++multithreading程序,每个线程设置为高优先级和亲和性。 在有16个核心的dell机器上编译运行这个代码,运行centos 7(Linux kernel – 3.10.0-229),禁用了超线程。 运行这段代码之后,我们的Linux机器在几秒钟内变得没有响应,因为如果我打开Eclipse编辑器,并在vi编辑器中保存文件或保存文件,这些应用程序就会挂起。 有趣的是,一旦我停止了这个程序/进程,那么所有其他的应用程序从他们离开的地方恢复。 此外,如果我从这10个线程中删除优先级,我不会看到这个问题。
问题 :
1)在16个内核中,有6个仍然在机器上(在CPU使用率上面显示,cpu执行了62.9%的用户空间,空闲了37.1%,有趣的是内核空间的CPU使用率为0%),那6个核心来处理其他应用程序,可能是其他应用程序无法运行的原因? 如何解决这个问题,而不引入睡眠/改变优先级?
2)想知道更好的方法,而不是在线程中引入睡眠/等待事件(这会导致内核上下文切换的最小延迟)以实现并行性?
冉顶命令( 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
突然剥夺内核使用任何活动核心的时间是无限的,并且是未知的。 在独占所有权之前,任何附属于该核心的内容都可能包含正在等待安排的线程,这些内容将永远丢失给系统。
不要这样做!
具有高优先级线程的紧密循环不是一个好主意……当打印hello只是循环而没有做任何事情时,在某些循环之后引入switchtothread / yield,并在更高的循环次数后将其置零。 这将使系统上的其他线程执行oppurtinity。当没有工作时,最终等待事件句柄。
@ kiran0x1B