是否可以在Linux上的Receive()调用中知道进程是否在阻塞状态中等待?
-
06-07-2019 - |
题
我的主要目的是以循环方式逐个执行进程,直到一个调用receive()并被阻塞,以便执行切换到队列中的下一个进程。有一个用Java编码的控制器应用程序,它使用Runtime.getRuntime()。exec()执行这些进程(也是Java应用程序)并保留作为Process对象的返回值。
为了达到这个目的,我需要捕获receive()调用(或它们被阻止的状态)并告诉控制器(主)应用程序。
如果可能的话,我可以按照你想要的那样低级。我的第一个想法是从驱动程序获取此信息,然后告诉我的控制器Java应用程序。我编写了一个linux内核网络模块来捕获发送和接收操作,但是aFAIK socket.receive()函数不会告诉网络驱动程序。
所以,我认为选项是从JVM获取此信息,以某种方式从Linux命令左右获取,或者可能通过Linux内核模块获取?
你有什么建议?
解决方案
如果您想知道您的线程是否被阻止,或者确切地知道它们被阻止了什么,您可以采取线程转储或使用像 jvisualvm 附加到流程并查看(在jvisualvm中,您将附加到流程,采取线程转储,然后查看每个线程的活动。)
其他提示
你看过 systemtap 吗?应该可以在最近的Fedora系统上随时使用。
最佳安德斯
我不知道这是否对您有所帮助,但您可以使用本地附件获取有关您计算机上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中,您将获得一个描述JVM中所有线程的ThreadInfos数组。
7)从TheadInfo#getThreadState()你可以检查状态是否是ThreadState.BLOCKED
您应该在工作进程中使用进程间通信原语来通知控制器应用程序它们已准备好接收数据。
您无法假设子进程如何实现其套接字读取。他们可以使用recv,select或poll等来等待网络数据。
这里实际上有几点。 Linux调度程序非常智能,可以预先阻止被阻止的任务。这意味着,如果你调用receive()并且没有什么可以等待接收,那么你的任务可能会被暂停,直到调用将返回。您不需要处理调度; Linux内核会为你做这件事。
那就是说,如果你需要知道你的任务是否被一些守护进程应用程序阻止,如果你愿意写一个LKM,为什么不在任务列表中找到你感兴趣的任务,并检查它的州?
当然,简单地检查任务的状态可能无法准确地告诉您所需的内容。如果您的任务状态是 TASK_INTERRUPTIBLE
,它只会告诉您您的任务正在等待某事,但要弄清楚这是什么东西可能不是一件小事。同样,您的任务可能处于 TASK_RUNNING
状态,并且当前并未实际在CPU上运行(但至少在 TASK_RUNNING
状态下您知道您的任务没有被阻止。)
您可以发送QUIT信号(控制台上的Ctrl- \)以获取线程转储。