global variable access synchronization between two processes - c

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.

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.

executable with mmap can use for multiple times?

I have an application which uses mmap for ipc. Can I run this application multiple times? Will it have any side effects ?
My application scenario:
my application forks off a child process whose job is to always kill the parent process randomly but it should do this in controlled manner, for example setting a variable in parent process which indicates the child process to kill the parent process (here comes the mmap). The parent process has a signal handler where it can resume the application again the child process kills the parent process it continues...
Can any one help me? thanks in adavnce
Whether running your application multiple times will have side effects or not depends on how you implement it. Please have a look at this answer. It contains a lot of helpful information. For example:
mmap is great if you have multiple processes accessing data in a read only fashion from the same file [...]
This mean: If you want to use the same shared memory for multiple parent/child pairs, then you need to synchronize access to that shared memory. Please have a look at this Q&A on how to do that. Of course, you have to make sure, that each parent/child pair uses its own variables in the shared memory.
Another option is to use a separate shared memory segment for each parent/child pair. You could do this, for example, by making the process ID of the parent process a part of the shared memory file name. Then, when you fork the child process, you pass the process ID (or the shared memory file name) to the child process, so that parent and child know which shared memory to use in order to comunicate to each other.

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.

Variable scope in 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.

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