0

我的主要目的是以循环方式一个接一个地执行进程,直到一个调用 receive() 并被阻塞,以便执行切换到队列中的下一个进程。有一个用 Java 编码的控制器应用程序,它使用 Runtime.getRuntime().exec() 执行这些进程(也是 Java 应用程序)并保留作为 Process 对象的返回值。

为了达到这个目的,我需要捕获接收()调用(或它们的状态,被阻塞)并将它们告诉控制器(主)应用程序。

如果可能的话,我可以尽可能地低级。我的第一个想法是从驱动程序获取此信息,然后将其告诉我的控制器 Java 应用程序。我编写了一个 linux 内核网络模块来捕获发送和接收操作,但是 AFAIK 的 socket.receive() 函数并没有告诉网络驱动程序任何东西。

所以,我认为选项是从 JVM 获取这些信息,以某种方式从 linux 命令或其他获取它,或者可能通过 linux 内核模块?

你有什么建议?

4

6 回答 6

1

你看过systemtap吗?应该可以在最近的 Fedora 系统上使用。

最佳安德斯

于 2009-06-19T11:44:34.233 回答
1

如果您想知道您的线程是否被阻塞,或者它们被阻塞的确切原因,您可以进行线程转储或使用jvisualvm之类的工具附加到进程并查看(在 jvisualvm 中,您将附加到进程,进行线程转储,然后查看每个线程的活动)。

于 2009-06-19T13:24:06.683 回答
1

我不知道这是否会对您有所帮助,但您可以使用本地附加获取有关您机器上 Java 线程状态的信息。

1) 将 tools.jar 添加到您的类路径并使用 VirtualMachine.list() 获取您机器上正在运行的 JVM 的列表。

2) 附加到使用 VirtualMachine.attach(virtualMachineDescriptor) 处理的 JVM

3) 获取本地连接器地址,vm.getAgentProperties().get("com.sun.management.jmxremote.localConnectorAddress");

4) 使用 JMXConnectorFactory.newJMXConnector(...) 连接到 JVM

5) 从 JMX 连接查找 ThreadMXBean

6) 从 ThreadMXBean 你得到一个 ThreadInfos 数组,它描述了 JVM 中的所有线程。

7) 从 TheadInfo#getThreadState() 您可以检查状态是否为 ThreadState.BLOCKED

于 2009-06-20T11:31:47.767 回答
0

您应该在工作进程中使用进程间通信原语来通知控制器应用程序它们已准备好接收数据。

您不能对子进程如何实现其套接字读取做出假设。他们可能正在使用recv、select、poll等来等待网络数据。

于 2009-06-19T11:41:09.920 回答
0

这里其实有几点。Linux 调度程序足够聪明,可以抢占一个被阻塞的任务。这意味着,如果您调用 receive() 并且没有等待接收的内容,您的任务可能会进入休眠状态,直到调用返回。您不需要处理调度;Linux 内核会为你做这件事。

也就是说,如果您需要知道您的任务是否被某个守护程序应用程序阻止,如果您愿意编写 LKM,为什么不直接在您感兴趣的任务列表中获取任务并检查其状态?

当然,简单地检查任务的状态可能无法准确地告诉您您想要什么。如果您的任务状态是TASK_INTERRUPTIBLE,它只会告诉您您的任务正在等待某事,但弄清楚那是什么可能并非易事。类似地,您的任务可能处于一种TASK_RUNNING状态,并且当前实际上并未在 CPU 上运行(但至少TASK_RUNNING处于您知道您的任务未被阻塞的状态)。

于 2009-06-19T13:33:59.223 回答
0

您可以发送一个 QUIT 信号(控制台上的 Ctrl-\)来获取线程转储。

于 2009-07-09T18:26:43.983 回答