views:

296

answers:

6

My main purpose is to execute processes one by one in a round-robin fashion until one calls receive() and is blocked, so that the execution switches to the next process in the queue. There is a controller application which is coded in Java and it executes these processes(which are also Java applications) using Runtime.getRuntime().exec() and keeps the return values which are Process objects.

To achieve this purpose, I need to capture the receive() calls(or their states, which is blocked) and tell them to the controller(master) application.

I can go as low-level as you want if this is possible.. My first thought was to get this information from the driver and then tell it to my controller Java application. I have written a linux kernel network module which captures the send and receive operations, but AFAIK the socket.receive() function does not tell anything to the network driver.

So, I think the options are to get this information from either the JVM, somehow get it from a linux command or so, or possibly through the linux kernel module?

What are your suggestions?

A: 

You should use interprocess communication primitives in your worker processes to notify the controller application that they are ready to receive data.

You can't make assumptions about how the child processes implement their socket read. They could be using recv, or select, or poll, etc., to wait for network data.

karunski
While that is certainly possible, this would require changing the code on the processes. Another purpose of mine is to be as independent as I could be from these processes, such that it will work with (almost)any process.
Ozan
+1  A: 

Have you looked at systemtap? Should be readily available on recent Fedora systems.

Best Anders

anders.norgaard
Hmm, this seems to capture the kernel system calls of the sockets. Which is the best option I believe.. Otherwise it would be Java application specific. I couldn't install it and try it out on Ubuntu 9.04 because it complained about kernel debug libraries etc., and I don't have the time right now to deal with it.. I will definitely try it though. This is the best way to go I think. Getting a stack trace and parsing it requires looking for many socket etc. classes functions that block while reading.
Ozan
+1  A: 

If you want to know if your threads are blocked, or exactly what they are blocked on, you can either take a thread dump or use a tool like jvisualvm to attach to the process and take a look (in jvisualvm you would attach to the process, take a thread dump, and then look at the activity of each thread).

matt b
Thread dump all the way...
Cem Catikkas
The thread still seems to be in Runnable state, however from the stack trace I can see the accept(), receive() etc. calls. While this seems to do the trick, I would need to execute jstack every ~200 ms to check if it is blocked or not and parse the output.(which is not very good on performance) So apparently, I need sort of an event-based solution, such that it will signal me when it is blocked on receive() etc. calls. It is a good solution though; if I didn't have to capture it (almost) when it happens.
Ozan
A: 

There are actually a few points here. The Linux scheduler is smart enough to pre-empt a blocked task. Meaning, if you call receive() and there's nothing waiting to receive, your task will probably be put to sleep until such a time that the call will return. You don't need to handle the scheduling; the Linux kernel will do it for you.

That said, if you need to know whether your task is blocked from some daemon application, if you're willing to write an LKM, why not just get the task in the task list that you're interested in, and check its state?

Of course, simply checking the state of the task might not tell you exactly what you want. If your task state is TASK_INTERRUPTIBLE, it only tells you that your task is waiting on something, but it might not be a trivial matter to figure out what that something is. Similarly, your task can be in a TASK_RUNNING state and not actually be running on the CPU at the current moment (but, at least, in the TASK_RUNNING state you know your task isn't blocked).

FreeMemory
+1  A: 

I don't know if this will help you, but you could get information about the state of a Java thread on your machine using local attach.

1) Add the tools.jar to your classpath and use VirtualMachine.list() to get a list of the running JVM on you machine.

2) Attach to the JVM processed using VirtualMachine.attach(virtualMachineDescriptor)

3) Get the local connector address, vm.getAgentProperties().get("com.sun.management.jmxremote.localConnectorAddress");

4) Use JMXConnectorFactory.newJMXConnector(...) to connect to the JVM

5) From the JMX connection lookup up the ThreadMXBean

6) From the ThreadMXBean you get an array of ThreadInfos that describes all threads in the JVM.

7) From TheadInfo#getThreadState() you can check if the state is ThreadState.BLOCKED

Kire Haglin
I haven't tried this, but using JStack it gives the Thread.State: RUNNABLE, so it would probably give me the same. Seems like I can't get this info from the Thread's states.
Ozan
A: 

You can just send a QUIT signal (Ctrl-\ on the console) to get a thread dump.

Ringding