2

今天发现了一个很奇怪的问题。我运行的是 Redhat Enterprise Linux 6,CPU 是 Intel E31275(4 核,8 线程)。我发现一个内核线程(我称之为 my_thread)不能正常工作。使用“ps”命令,我发现 my_thread 的状态一直在运行:

ps ax
5545 ?        R      3:14 [my_thread]
15774 ttyS0    Ss     0:00 -bash
...

但它的运行时间始终是 3 点 14 分。既然它正在运行,为什么总时间没有增加?从 proc 文件 /proc/5545/sched 中,我发现该线程的所有统计信息(包括唤醒计数 (se.nr_wakeups))也始终相同。

从 /proc/5545/stack 中,我发现这个线程调用了这个函数并且从未返回:

interruptible_sleep_on_timeout(&q, 3*HZ);

理论上,如果没有其他线程唤醒该线程,该函数将每 3 秒返回一次。每次函数返回后,/proc/5545/sched 中的 se.nr_wakeups 都会增加 1。但是在我发现线程有问题之后,这种情况就再也没有发生过。

有没有人有一些想法?interruptible_sleep_on_timeout() 是否有可能永远不会返回?

更新:如果我为此线程设置 CPU 亲和性,我发现问题不会发生。如果我把它固定到一个专用的核心上,那么一切都很好。SMP调度有问题吗?

再次更新:我在BIOS中禁用超线程后,直到现在我才看到这样的问题。

4

1 回答 1

4

首先,R 表示线程未处于运行状态但可运行。也就是说,这并不意味着它运行,它意味着它处于允许调度程序选择它运行的状态。两者有很大的不同。

在类似的意义上,interruptible_sleep_on_timeout(&q, 3*HZ); 不会在 3 个 jiffies 之后运行线程,而是让它在 3 个 jiffies 之后运行 - 实际上你在“ps”中看到它可以运行,所以可能确实发生了超时。

由于您没有提及有关内核线程的任何内容,因此我什至不知道它是在您自己的代码中还是在标准内核代码中,所以我无法真正详细回答。

您描述的情况的一个可能原因是其他一些线程(用户或内核)的优先级高于您的线程,因此调度程序永远不会选择它来运行。如果是这样,它可能不是以实时优先级(SCHED_FIFO 或 SCHED_RR)运行的线程。

于 2011-10-21T14:43:23.307 回答