Variable scope in C - c

I have a main() function and prior to declaring main(), I declare global variables.
Then inside main() 2 processes start: 1 child and 1 parent via fork(). Why can't the parent and child processes share the global variables I declared? What is a good way to handle this? Thank you.

When you fork() you're spawning a new process. Everything at the time of the fork is copied, but after that ... nothing is shared.
You have two choices at that point:
Keep a pipe open between your two processes and communicate changes
Re-write your code to be multi-threaded, where you can access the same data (using locks)

With fork() you create a new process with separate memory space. To communicate between processes you can use signals (using kill())
If you want to share variables, consider using threads (e.g. pthread.h). Then you can use events or mutexes for thread synchronization.

Related

How to run 2 parallel processes in C? [duplicate]

Consider this simple code:
int myvar = 0;
int main() {
if (fork()>0) {
myvar++;
} else {
// father do nothing
}
}
When child increments myvar, is the value shared with the father (like pthread)?
No and yes.
No, they are not shared in any way which is visible to the programmer; the processes can modify their own copies of the variables independently and they will change without any noticable effect on the other process(es) which are fork() parents, siblings or descendents.
But yes, the OS actually does share the pages initially, because fork implements copy-on-write which means that provided none of the processes modifies the pages, they are shared. This is, however, an optimisation which can be ignored.
If you wanted to have shared variables, put them in an anonymous shared mapping (see mmap()) in which case they really will get shared, with all the caveats which come with that.
fork()ing creates an exact copy of the parent process at the time of forking. However, after the fork() is completed, the child has a completely different existence, and will not report back to the parent.
In other words, no, the parent's global variables will not be altered by changes in the child.
After fork(), the entire process, including all global variables, is duplicated. The child is an exact replica of the parent, except that it has a different PID(Process Id), a different parent, and fork() returned 0. Global variables are still global within its own process. So the answer is no, global variables are not shared between processes after a call to fork().
No, since global variables are not shared between processes unless some IPC mechanism is implemented. The memory space will be copied. As a consequence, the global variable in both processes will have the same value inmediately after fork, but if one changes it, the other wont see it changed.
Threads on the other hand do share global variables.

global variable access synchronization between two processes

I have a global boolean variable that both parent and child process can write to. The child process is just forked (no exec() called).
In C/Linux, how do I go about synchronizing access to this global? In C/C++ threading world, I could have used a mutex.
After calling fork, each process has its own copy of any variables in use. The global variable in the parent and the global in the child are completely distinct from each other, so they can't be used as a common variable.
If you want the two processes to share data, you would need to either create a pipe using the pipe function to pass data between the two, or you would need to create a shared memory segment that both processes would have access to.

backgrounding a threaded application with fork()

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).

After forking, are global variables shared?

Consider this simple code:
int myvar = 0;
int main() {
if (fork()>0) {
myvar++;
} else {
// father do nothing
}
}
When child increments myvar, is the value shared with the father (like pthread)?
No and yes.
No, they are not shared in any way which is visible to the programmer; the processes can modify their own copies of the variables independently and they will change without any noticable effect on the other process(es) which are fork() parents, siblings or descendents.
But yes, the OS actually does share the pages initially, because fork implements copy-on-write which means that provided none of the processes modifies the pages, they are shared. This is, however, an optimisation which can be ignored.
If you wanted to have shared variables, put them in an anonymous shared mapping (see mmap()) in which case they really will get shared, with all the caveats which come with that.
fork()ing creates an exact copy of the parent process at the time of forking. However, after the fork() is completed, the child has a completely different existence, and will not report back to the parent.
In other words, no, the parent's global variables will not be altered by changes in the child.
After fork(), the entire process, including all global variables, is duplicated. The child is an exact replica of the parent, except that it has a different PID(Process Id), a different parent, and fork() returned 0. Global variables are still global within its own process. So the answer is no, global variables are not shared between processes after a call to fork().
No, since global variables are not shared between processes unless some IPC mechanism is implemented. The memory space will be copied. As a consequence, the global variable in both processes will have the same value inmediately after fork, but if one changes it, the other wont see it changed.
Threads on the other hand do share global variables.

pthread and child process data sharing in C

my question is somewhat conceptual, how is parent process' data shared with child process created by a fork() call or with a thread created by pthread_create()
for example, are global variables directly passed into child process and if so, does modification on that variable made by child process effect value of it in parent process?
i appreciate partial and complete answers in advance, if i'm missing any existing resource, i'm sorry, i've done some search on google but couldn't find good results
thanks again for your time and answers
The semantics of fork() and pthread_create() are a little different.
fork() will create a new process, where the global variables will be separate between the parent and children. Most OS implementations will use copy-on-write semantics, meaning that both the parent and child process will use the same physical memory pages for all global variables until one of the processes attempts to edit the physical memory, at which point a copy of that page is made, so that now each process gets its own copy and does not see the other process's, so that the processes are isolated.
pthread_create() on the other hand, creates a new thread within the same process. The new thread will have a separate stack space from the other running threads of the same process, however the global variables and heap space are shared between all threads of the same process. This is why you often need a mutex to coordinate access to a shared piece of memory between multiple threads of the same process.
TL;DR version: with fork(), you don't see the other guy's changes; with pthread_create() you do.
A fork creates an almost exact copy of the calling process, including memory and file descriptors. Global variables are copied along with everything else, but they are not in any way linked to the parent process. Since file descriptors are also copied, parent and child can interact via these (as long as they're setup properly, usually via pipe or socketpair).
There's a big difference between processes created by fork and between threads created with pthread_create. Processes don't share global variables and should communicate through pipes, sockets, or other tools provided by the OS. A good solution is MPI - which is a message-passing library for inter-process communication.
Threads are quite different. A thread created with pthread_create shares all the global variables with its caller. Moreover, the caller can pass an arbitrary structure into the thread, and this structure will also be shared. This means that one should be extremely careful when programming with threads - such amounts of sharing are dangerous and error prone. The pthread API provides mutexes and conditions for robust synchronization between threads (although it still requires practice and expertise to implement correctly).

Resources