User processor time for a specific child process after the first output to standard output

I am working on a program that can spawn multiple child processes, and I need to get accurate information about the processor time used by each child process, even if several child processes are running at the same time. I do this using wait4 (2) in a separate thread of the parent process, which works quite well.

However, this approach provides the total time spent on a particular child process, and I'm only interested in the amount of time spent after a certain event, namely: the first output of the child process to standard output. I looked at other ways to get the processor time of child processes, such as getrusage (2) and times (3), but they don't seem to be able to distinguish between multiple times of child processes and instead provide the sum of all times of child processes.

I am working on a text editor that allows users to run scripts and code in different languages, and the application has a built-in time synchronization function. The application uses bash scripts to run user code, and the first thing my bash scripts do is output the byte of the initial header (0x02). After that, the bash script does everything it takes to run the user code, and that is what I want time to do. bash can do a bit of initialization (to set PATH variables, etc.), which can take 30 or 40 ms, and I don't want the initialization to be synchronized with the rest. If the user code is, for example, a simple program like Hello World in C, the synchronization function can display about 41 ms instead of the actual 1 ms that was required to run their code.

Any ideas on how to do this?

Thanks:)

+4
source share
1 answer

A couple of possible solutions come to mind. They do not get processor time after the first output for sure, but they can avoid the problem you are dealing with.

First, get rid of bash scripts and just do the equivalent work in your program before running user code (for example, between fork() and exec() ). Thus, the child process "processor time from wait4() does not include your additional configuration.

Another possibility is to write a simple application that does nothing but launch the user application and transfer its processor time back to the main application. Then this runner application can be called from your scripts to run the user program, and not directly access the user program. A runner application can use fork() / exec() / wait4() to start a user program and can report information from wait4() to your main program using any of a variety of methods, such as a named pipe, queue message, socket, or even just writing information to a file that your main program can open. Thus, your bash scripts can work both before and after starting a user program that will not be included in the processor time specified by the runner application. You would probaby want the runner to accept an argument, such as a channel name or output file, in addition to the path and arguments of the user program so that you can control how the information is reported - so you could run more than one instance of the runner application and that's it still retain the information they report separately.


If you want to include the work done with the script, but not the bash boot time, then you can signal the main program by repeating something in the pipe from the bash script before and after the parts you want to find. Then the main program can measure the time between the start and stop signals, which at least will give you the wall time (although not the actual processor time). Otherwise, I'm not sure if there is a way to ideally measure processor time for only part of the script without using modified bash (which I would have avoided if possible).

+3
source

Source: https://habr.com/ru/post/1390340/


All Articles