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.
Related
I am just going to post pseudo code,
but my question is I have a loop like such
for(i<n){
createfork();
if(child)
/*
Exit so I can control exact amount of forks
without children creating more children
*/
exit
}
void createfork(){
fork
//execute other methods
}
Does my fork create a process do what it is suppose to do and exit then create another process and repeat? And if so what are some ways around this, to get the processes running concurrently?
Your pseudocode is correct as written and does not need to be modified.
The processes are already executing in parallel, all six of them or however many you spawn. As written, the parent process does not wait for the children to finish before spawning more children. It calls fork(), checks if (child) (which is skipped), then immediately proceeds to the next for loop iteration and forks again.
Notably, there's no wait() call. If the parent were to call wait() or waitpid() to wait for each child to finish then that would introduce the serialism you're trying to avoid. But there is no such call, so you're good.
When a process successfully performs a POSIX fork(), that process and the new child process are initially both eligible to run. In that sense, they will run concurrently until one or the other blocks. Whether there will be any periods of time when both are executing machine instructions (on different processing units) depends at least on details of hardware capabilities, OS scheduling, the work each process is performing, and what other processes there are in the system and what they are doing.
The parent certainly does not, in general, automatically wait for the child to terminate before it proceeds with its own work (there is a family of functions to make it wait when you want that), nor does the child process automatically wait for any kind of signal from the parent. If the next thing the parent does is fork another child, then that will under many circumstances result in the parent running concurrently with both (all) children, in the sense described above.
I cannot speak to specifics of the behavior of your pseudocode, because it's pseudocode.
I have an array of processes, and I have to implement all of them parallelly. As the number of processes depends on the size of the array, how do I carry out this question? I'm assuming I have to use fork() or threads but I am not sure how. And how do I return immediately after the process has been carried out? Thanks!
First let's get a few things straight:
fork() is on POSIX systems the system call to split one process into two. The child process will be indicated by a return code of 0, and the parent by The Pid of the child (returning immediately while the child may be created/executing/dying). Aside from that, the two are essentially identical, which means the child needs to carry out the specific sub-processing (usually by means of execve()ing) another binary), while the parent wait4()s the child. Another option is to not wait4(), but instead listen for SIGCHLD, sent when the child terminates.
Multiple threads all happen in the same process. Meaning that the sub processing is carried out by code blocks/functions in the same address space.
It's not clear from your question - so - If your array of processes is essentially an array of command lines, you use fork() and execve(), above. If it's an array of functions, use threads.
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 have a process that forks, performs computation and writes out data to stdout. The child process also writes out data to stdout after performing some computation. Currently, the output from the parent and the child come out separately. However, I'm concerned that the output from the child may be printed mixed with the output from the parent.
I.e. I have this line in both the child and the process :-
fprintf(stdout, "%s\n", do_computation());
Is there any neat way to prevent the writes from being interleaved? It hasn't happened so far, however I'm concerned that it may.
This is the standard multitasking issue, and is solved the same way any other shared resource is protected: it's your responsibility to create and manage semaphores so the processes can negotiate periods of exclusive access to shared resources such as these streams, or to arrange similarly safe mechanisms for them to communicate amongst themselves (eg having the child processes respond not to stdout but via a pipe per process back to the parent, and having the parent poll those pipes and report their results as complete messages become available).
There should be plenty of good tutorials on the web on multiprocess programming in C.
Conceptually, you want to achieve before-or-after atomicity for the fprintf calls in different process. You can in the parent process, waitpid for the child process right before the fprintf call so that the call in parent process is guaranteed to be executed after the child terminates without reducing the parallelism of the computation.
So I have an application which uses threads. Now when the program first starts up, I want it to go through setting up database connections and whatnot before it backgrounds itself so that whatever/whoever starts the program can know if there was an error starting up.
I did some looking around and have found some resources that say 'do not mix fork and threads', while others say that forking in linux will only duplicate the main thread and leave the others alone.
In the case of the latter (where it just duplicates the main thread), how then do the threads access file level (global) variables? Will the threads not be able to access the variables that are now in the forked process's address space?
Ultimately the goal is to have the application background itself after threads have been created. If this is not possible, I can put the fork before the thread creation, just would like to do it as late as possible.
Note: at the time of the fork, the threads will be doing a sleep() loop until the main thread puts data into a shared variable for them to process. So if the sleep gets interrupted, they wont be harmed.
There is no way to duplicate threads as part of the fork, and the parent's threads will all terminate when the parent exits, so even if they could access the child's memory, it wouldn't help you. You need to either create your threads after forking, or use pthread_atfork to register handlers that will recreate them in the child process. I would recommend just waiting until after forking to create your threads since it's a lot simpler and more efficient.
Why is it that you want to delay forking as long as possible? If you want to maintain connection to a terminal or something until initialization is finished, you can just have the parent process wait to terminate until the child process (with its threads) is done initializing and ready to be "in the background". Various synchronization tools could be used to accomplish this. One simple one would be opening a pipe through which the child sends its output back to the parent to display; the parent could simply exit when it receives EOF on this pipe.
Forking a process creates two different processes and threads in one process will not be able to access memory in the second process. If you want different processes to access the same memory, you want something called shared memory.
When a thread in a process calls fork(), a new process is created by copying, among other things, (1) the full address space of the process and (2) the (one) thread that called fork. If there are other threads in the process, they don't get copied. This will almost certainly lead to bugs in your program. Hence the advice not to mix threads and forks.
If you want to create a background process with many threads, you must fork it before spawning any other thread. Then, the two processes behave normally, like any two isolated processes: threads within one process share the same memory, but your background threads and your foreground process won't share any memory (by default).