Why is there timing problem while to fork child processes - fork

When I took a look at the reference of 'Launching-Jobs' in gnu.org, I didn't get this part.
The shell should also call setpgid to put each of its child processes into the new process group. This is because there is a potential timing problem: each child process must be put in the process group before it begins executing a new program, and the shell depends on having all the child processes in the group before it continues executing. If both the child processes and the shell call setpgid, this ensures that the right things happen no matter which process gets to it first.
There is two method on the link page, launch_job () and launch_process ().
They both call the setpgid in order to prevent the timing problem.
But I didn't get why is there such a problem.
I guess new program means result of execvp (p->argv[0], p->argv); in launch_process(). And before run execvp, setpgid (pid, pgid); is always executed, without same function on launch_job ().
So again, why is there such a problem? (why we have to call setpgid (); on launch_job () either?)

The problem is that the shell wants the process to be in the right process group. If the shell doesn't call setpgid() on its child process, there is a window of time during which the child process is not part of the process group, while the shell execution continues. (By calling setpgid() the shell can guarantee that the child process is part of the process group after that call).
There is another problem, which is that the child process may execute the new program (via exec) before its process group id has been properly set (i.e. before the parent calls setpgid()). That is why the child process should also call setpgid() (before calling exec()).
The description is admittedly pretty bad. There isn't just one problem being solved here; it's really two separate problems. One - the parent (i.e. the shell) wants to have the child process in the right process group. Two - the new program should begin execution only once its process has already been put into the right process group.

Related

Is it possible to make a console wait on another child process?

Usually when a program is run from the Windows console, the console will wait for the process to exit and then print the prompt and wait for user input. However, if the process starts a child process, the console will still only wait for the first process to exit. It will not wait for the child as well.
Is there a way for the program to get the console to wait on another child process instead of (or as well as) the current process.
I would assume it's impossible because presumably the console is waiting on the process' handle and there's no way to replace that handle. However, I'm struggling to find any confirmation of this.
Is there a way for the program to get the console to wait on another child process instead of (or as well as) the current process.
No. As you noted, as soon as the 1st process the console creates has exited, the console stops waiting. It has no concept of any child processes being created by that 1st process.
So, what you can do instead is either:
simply have the 1st process wait for any child process it creates before then exiting itself.
if that is not an option, then create a separate helper process that creates a Job Object and then starts the main process and assigns it to that job. Any child processes it creates will automatically be put into the same job as well 1. The helper process can then wait for all processes in the job to exit before then exiting itself. Then, you can have the console run and wait on the helper process rather than the main process.
1: by default - a process spawner can choose to break out a new child process from the current job, if the job is setup to allow that.

IContextMenu::InvokeCommand, break away from job?

I have a child process in a job that has JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE specified.
When I invoke IContextMenu::InvokeCommand, though, any processes that are started are automatically killed when my child process exits, because they are automatically included in a job.
How can I prevent this from happening?
The solution I've found is to specify
JOB_OBJECT_LIMIT_BREAKAWAY_OK | JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK
for the child process, to allow its children to automatically break away from the job.

Spawning simultaneous child processes in Ruby

I'm using resque, with a queue processor which, as part of its execution, will start a shell process. Currently, I am using PTY.spawn() to invoke the shell command and handle its output.
I'd like to augment this code so that a quantity (N) can be given (the command executed onboards VMs, I want to be able to start a variable number with one call), and have the shell process be called N times in separate processes, without the Nth call having to wait for call N-1 to finish, and so on. I also want to capture all STDOUT from each invocation, so that I can do work on the output once the call is done.
I have looked at Kernel::fork but the scope of code inside a forked block is not the same as its parent (for pretty obvious reasons).
What tool(s) can I use so that each process can be spawned independently, their output can be captured, and I can still have the parent process wait for them all to finish before moving on?
Here:
stdouts=[]
numberOfProcesses.times do
stdouts<<PTY.spawn(command_line)[0..-1]
end
That's pretty basic if you just spawn them and get a bunch of STDOUT/STDIN pairs. If you want to be able to work on each process's output as soon as it is done, try this:
threads=[]
numberOfProcesses.times do
threads<<Thread.new(command_line) |cmd|
stdout, stdin, pid = PTY.spawn(cmd)
Process.waitpid(pid)
process_output(stdout.read)
end
end
threads.each {|t| t.join}
That spawns them in parallel, each thread waiting for when it's instance is done. When it's instance is done, it processes output and returns. The main thread sits waiting for all of the others to finish.

How to catch console-closing event?

The context of my problem is:
I have a Windows .NET app (GUI) running as a main process.
From this (parent) process, I create a couple of sub-processes as console processes.
The main process sends data to the children processes through named pipes.
In the main app, I have a list of the sub-processes.
My probleme is that each console has a close ("x") button and can be terminated (whatever the way it is). Since I keep a list of the created consoles in my main app, I would like to know when a console is killed or exited.
My console (child process) program is simply a "main()" with a loop function that reads the pipe (and displays the data). It has no message system or whatever else that could handle a windowing "exit".
The first idea that comes to my head is to poll the sub-processes from the main app to refresh the list. But this means I have to introduce a timer or a thread that watches the consoles. I don't like the idea.
Does someone have a better idea?
WaitForSingleObject(hThread, 0) will tell you whether the thread specified in hThread argument is signaled and therefore finished. Same goes to hProcess.
Both handles of your child process are returned after CreateProcess() call. You can either close them immediately, or monitor using WaitForSingleObject.

Attach gdb to process before I know the process id

I am debugging a process on a web server running Linux. The process is invoked once a request is coming from a web-page. In order to debug the process, I look at the running processes list (using top), I spot the relevant process (named apache2) by it's CPU usage (quite easy, since it is usually on top of the list), and I attach the gdb session to the process id. Of course I can call the attach PID command only after the process is up.
The only problem is that this process-id-spotting takes a second or two, so I cannot stop at functions which are called during the first second or two. (The whole process takes about a minute so in most cases it is not a problem).
Is there any way of doing this automatically, so I can save these couple of seconds and start the attachment earlier?
You can attach to the parent process and catch forks. Don't forget to set follow-fork-mode child.

Resources