I need to create a multi-process program that:
Creates 5 processes using fork();
Sends stuff to do the the child processes using pipes
When a child process completes its stuff, it should receive new stuff to do from parent process until all stuff are completed.
Right now my idea is to wait() on completed child tasks (and it exits) and then to create a new child process so I always have a maximum of 5 processes.
Is there a way to "re-use" the already existing process? Maybe "signaling" something? Cannot find it on Google.
Using C.
I solved my problem in this way:
Children write the result of their calculation on a pipe A (this pipe is not blocking). Then they wait their next input on a pipe B (this pipe is blocking).
Parent loops on all children trying to read something from pipe A (this pipe is not blocking so parent goes on if child didn't send anything). If pipe A contains a result, the parent sends another task to that child on pipe B.
There is a pipe A and a pipe B for each child.
Related
I have a while loop that reads data from a child process using blocking I/O by redirecting stdout of the child process to the parent process. Normally, as soon as the child process exits, a blocking read() in this case will return since the pipe that is read from is closed by the child process.
Now I have a case where the read() call does not exit for a child process that finishes. The child process ends up in a zombie state, since the operating system is waiting for my code to reap it, but instead my code is blocking on the read() call.
The child process itself does not have any child processes running at the time of the hang, and I do not see any file descriptors listed when looking in /proc/<child process PID>/fd. The child process did however fork two daemon processes, whose purpose seems to be to monitor the child process (the child process is a proprietary application I do not have any control over, so it is hard to say for sure).
When run from a terminal, the child process I try to read() from exits automatically, and in turn the daemon processes it forked terminate as well.
Linux version is 4.19.2.
What could be the reason of read() not returning in this case?
Follow-up: How to avoid read() from hanging in the following situation?
The child process did however fork two daemon processes ... What could be the reason of read() not returning in this case?
Forked processes still have the file descriptor open when the child terminates. Hence read call never returns 0.
Those daemon processes should close all file descriptors and open files for logging.
A possible reason (the most common) for read(2) blocking on a pipe with a dead child, is that the parent has not closed the writing side of the pipe, so there's still an open (for writing) descriptor for that pipe. Close the writing side of the pipe in the parent process before reading from it. The child is dead (you said zombie) so it cannot be the process with the writing side of the pipe open. And don't forget to wait(2) for the child in the parent, or you'll get a system full of zombies :)
Remember, you have to do two closes in your code:
One in the parent process, to close the writing side of the pipe, leaving the parent process with only a reading descriptor.
One in the child process (just before exec(2)ing) closing the reading side of the pipe, leaving the child process only with a writing descriptor.
In case you want to use the pipe(2) to send information to the child, change the reading for writing and viceversa in the above two points.
My book on C applied to Linux, says that if a process creates a child with a fork(), then the pipe created between them follow this principle:
It is important to notice that both the parent process and the child process initially close their unused ends of the pipe
If both processes start with their pipe-end closed, how they know when the other is free to communicate? Maybe, is there an intermediate buffer between the processes?
Pipes on computers works very much like pipes in real life. There are two ends, you put something into one end and it comes out the other end.
Normally when using pipes in a program, you usually only want the input-end, where you write data, or you want the output-end, where data is read from. If the parent process only wants to write to the child process, and the child process only reads from the parent process, then the parent process could close the read end after the fork, and the child process can close the write end.
Pipe is an interprocess communication mechanism provided by the kernel. A process writing on the pipe need not worry whether there is some other process to read it. The communication is asynchronous. The kernel takes care of the data in transit.
I'm looking for a way to read from STDIN(console) in child process, after closing parent process.
My program should be like:
parent process forks and creates child process.
After creating child process, parent MUST be closed. I can not use functions such as wait() etc.
The thing is, when I exit from parent process, I can not read from console anymore. Is there any way to 'pass the control' to child process, instead of passing it back to shell ?
Instructions:
Process 1: reads data (sigle lines) from standard input stream and passes it with ipc message queue to process 2.
Process 2: receives data send by process 1 and prints it in standard output stream.
Two processes should be executed automatically from 1 initiative process. After executing child processes, initiative process should immediatelly close.
I am currently writing a program in C using Linux in which a parent process creates a child process and then that child process creates another child processes (so three processes total). I have to pipe a string from parent to the first child process and then from the first child process to the child of that process. I am currently piping the string from parent to child using code similar to this (all code not shown):
pipe(pipeArray)
write(pipeArray[1], myString, length);
close(pipeArray[1]);
read(pipeArray[0], FirstProcessString, length+1);
close(pipeArray[0]);
My problem is the second part of of my program in which now I must take the string from the second child process and pipe it all the way up to the first parent process. How do you pipe from the second child process to the original parent process (the first process)? I have tried variations of this code in order to pipe up with no luck and also researched this topic and was not able to find anything helpful.
I am writing a C program that creates # childs and let's them do a single task and report the result back to the main. After writing to the pipe they have to wait for another request.
I have communication in one direction working with a pipe but I have no way of knowing where (or better, from who) the data is coming from.
Is there any way to know the child's PID in the parent when there is no way of knowing which child wrote on the pipe?
Edit
I have an array with all PID's of the childs but when reading out the pipe, I have no way of knowing where the data came from.
Thanks!
Create one pipe for each child and use select or poll to listen to all of them at once.
Either do like Zack says (one pipe per child) or change your protocol in such a way that the child reports its pid as part of the message.
fork() returns the pid of the child to the parent process and 0 to the child, you could store them in an array or link list to keep track of them