Multiple fork()'s. How does main know pid? - c

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

Related

Assign new tasks to forked() processes

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.

Forked processes order of execution

I know there's another thread with the same name, but this is actually a different question.
When a process forks multiple times, does the parent finish executing before the children? Vice versa? Concurrently?
Here's an example. Lets say I have a for loop that forks 1 parent process into 4 children. At the end of that for loop, I want the parent process to feed some data to the children via pipes. The data is written to each child process' respective stdin.
Will the parent send the data first, before any of the children execute their code? This is important, because we don't want it to start working from an invalid stdin.
The order of the execution is determined by the specific OS scheduling policy and not guaranteed by anything. In order to synchronize the processes there are special facilities for the inter-process communication (IPC) which are designed for this purpose. The mentioned pipes are one example. They make the reading process to actually wait for the other process to write it, creating a (one-way) synchronization point. The other examples would be FIFOs and sockets. For simpler tasks the wait() family of functions or signals can be used.
When a process forks multiple times, does the parent finish executing before the children? Vice versa? Concurrently? -
Concurrently and depends on the scheduler and its unpredictable.
Using pipe to pass integer values between parent and child
This link explains in detail about sharing data between parent process and child.
Since you have four child process you may need to create different individual pipes between each child process.
Each byte of data written to a pipe will be read exactly once. It isn't duplicated to every process with the read end of the pipe open.
Multiple child processes reading/writing on the same pipe
Alternatively you can try shared memory for the data transfer.
They will execute concurrently. This is basically the point of processes.
Look into mutexes or other ways to deal with concurrency.

Can a parent function tell if a child has written to stdin?

For instance let's say the parent function has:
scanf("%s", str);
if (strcmp(str,"test")==0)
printf("Success!\n);
and here is the child function:
signal(SIGUSR1, speak);
sleep(5);
kill(0, SIGUSR1)
and the sleep function is:
void speak()
{
puts("test");
}
How come the parent function never reaches success? Is it because puts function doesn't write from the keyboard? Is there a way I can work around this?
How come the parent function never reaches success? Is it because puts function doesn't write from the keyboard? Is there a way I can work around this?
I suppose that you allow the child process to inherit its standard streams from the parent, so that they are shared by parent and child. You seem to have the very odd idea that data written to stdout should feed back to stdin. Although it is possible to arrange for that by creating a pipe and reassigning the standard streams, it is by no means normal to do so, much less automatic.
If you want to perform IPC between two processes via stream I/O, then creating a pipe between them is one of the few ways to do it, and probably the easiest. Especially so when the processes are related as parent / child.
we can do redirection without using pipe.As far as I understood your target is to print to the stdout by the the child process and reading from the stdin by the parent process.
Here is a solution:
freopen("myfile.txt","r",stdin);------>do this at the parent process after the child is created.
freopen("myfile.txt","w",stdout);------>do this in child process after the child is created.

Why cant a pipe created using pipe() be used as a bi-directional pipe?

Almost all the pipe examples I've seen advice closing the unused write/read ends. Also man clearly states that pipe() creates a pipe, a unidirectional data channel But I've tried reading and writing to both ends of the pipe in both the parent and the child and everything seems to be OK.
So my doubt is why do we need 2 pipes if two processes have to both read and write to each other and why not do it using a single pipe?
If you use the same pipe how does the child separate its messages from the parents messages and vice versa?
For example:
Parent writes to pipe
Parent reads from pipe hoping to get message from child but gets its own message :(
It is much easier to use one pipe for child->parent and another pipe for parent->child.
Even if you have some protocol for reading/writing it is quite easy to deadlock the parent and child process.
You can read and write at both ends of the created pipe, but uni-directional means that data only travels in one direction at any time, from parent to child or vice versa. Two pipes are needed for non-blocking sending and receiving of data, meaning that you can read and write at the same time with two pipes, but with one pipe you must finish reading before you can write to the pipe or you must finish writing something before you can read the pipe. In layman terms, you can only read or write at any point of time with only one pipe

c language problem

i have a c problem can any one help me . i wrote a code of process creation in c language , it uses pid & fork() call. the fork call is use for making child process now can any body tell me how to make parent process? i know that creating a child in process make the process parent automatically but i want to make a parent process right from the start so can any one tell me how to do this,
Secondly i just create the process i don't know how to use it i cant assign any work(computation) to it.so can any one tell me how to use the process for work?
Third one i want to give a name to my process how can i do it & how i can control their execution?
please if anyone can enlighten me than please help me to understand all this.
i shall be thank full for this forever
thanks in advance
The fork call creates a new process that is identical to the existing process except for a few minor differences such as its pid, parent pid. The original process carries on from exactly the same place and this is the parent process. Which means your question is basically meaningless. You don't create the parent process, the original process becomes the parent process once it creates a child process.
It's a bit like asking "I created a child by getting pregnant and giving birth, but how do I create the parents?" You are a parent automatically.
Back to computers...
When you fork, the system call returns the pid of the child to the parent and 0 to the child, so you should have code something like:
int pid = fork();
if (pid == 0)
{
// in child, do child processing - normally exec an executable
}
else if (pid > 0)
{
// in parent, do some processing - often wait for child to complete
}
else
{
// fork failed - handle the error
}
When you fork a process, one process becomes two processes. Each continues running at exactly the same place. The only difference is that the fork returns the PID of the child process to the parent process and returns the value 0 to the child process.
Without any help, the child process does not know its parent. If the two processes need to communicate with one another then they will need to use some sort of IPC mechanism.
A common form of IPC is pipe. If one opens pipes before forking, then both the child and the parent keep the open file descriptors. This will allow both processes to communicate with one another. The parent is now free to communicate its PID to the child process if so desired.
Secondly i just create the process i don't know how to use it i cant assign any
work(computation) to it
You need to use fork and exec in pair make it run the program you want to execute.
Here is the wiki link for more information.
Fork-exec is a commonly used technique in Unix whereby an executing process spawns a new program. fork() is the name of the system call that the parent process uses to "divide" itself ("fork") into two identical processes. After calling fork(), the created child process is actually an exact copy of the parent - which would probably be of limited use - so it replaces itself with another process using the system call exec().
To create a parent process, take your code for creating a child and reverse the roles of parent and child. Presto change-o, the new process is the parent and the old process is the child.
For communications between the processes, use a pipe(2), or several. Also, there is shared memory.
To control execution, use kill(2) and wait(2). I'm not sure about assigning names, we might need to know what platform you're on.
About renaming (I assume you mean the name displayed by ps), to "rename" a process, just copy your new name into argv[0]

Resources