【发布时间】:2016-04-13 16:27:30
【问题描述】:
期望的行为:在一组已使用isolcpus 隔离的内核上运行多线程 Linux 程序。
这是一个小程序,我们可以将其用作多线程程序的示例:
#include <stdio.h>
#include <pthread.h>
#include <err.h>
#include <unistd.h>
#include <stdlib.h>
#define NTHR 16
#define TIME 60 * 5
void *
do_stuff(void *arg)
{
int i = 0;
(void) arg;
while (1) {
i += i;
usleep(10000); /* dont dominate CPU */
}
}
int
main(void)
{
pthread_t threads[NTHR];
int rv, i;
for (i = 0; i < NTHR; i++) {
rv = pthread_create(&threads[i], NULL, do_stuff, NULL);
if (rv) {
perror("pthread_create");
return (EXIT_FAILURE);
}
}
sleep(TIME);
exit(EXIT_SUCCESS);
}
如果我在没有独立 CPU 的内核上编译和运行它,那么线程会分布在我的 4 个 CPU 上。好!
现在如果我将isolcpus=2,3 添加到内核命令行并重新启动:
- 在没有任务集的情况下运行程序会将线程分配到核心 0 和 1。这是预期的,因为默认的关联掩码现在不包括核心 2 和 3。
- 使用
taskset -c 0,1运行具有相同的效果。很好。 - 使用
taskset -c 2,3运行会导致所有线程进入同一个核心(核心2 或核心3)。这是不希望的。线程应该分布在核心 2 和 3 上。对吧?
This post 描述了一个类似的问题(尽管给出的示例离 pthreads API 更远)。 OP 很高兴通过使用不同的调度程序来解决这个问题。不过,我不确定这是否适合我的用例。
有没有办法使用默认调度程序将线程分布在隔离的核心上?
这是我应该报告的内核错误吗?
编辑:
如果您使用像 fifo 调度程序这样的实时调度程序,确实会发生正确的事情。详情请参阅man sched 和man chrt。
【问题讨论】:
-
就我个人而言,我没想到会有这样的行为。向 LKML 发送电子邮件,检查为什么默认调度程序无法跨已通过
taskset分配的隔离内核迁移。
标签: linux multithreading scheduler affinity