Reputation: 7128
I'm expecting this code
void func(int* count)
{
*count += 1;
char* buf[100];
sprintf(buf, "%d -> %d\n", count, *count);
write(1, buf, strlen(buf));
}
int main()
{
int* count = 0;
int pid = fork();
if(pid == 0)
{
func(&count);
}
else
{
func(&count);
}
return 0;
}
will print
1444711088 -> 1
1444711088 -> 2
because 2 fork using same memory cell (1444711088) for count
variable and when one of them modify the value of it, other one will be affected. But it's not working as expected. It's printing this :
1444711088 -> 1
1444711088 -> 1
Can you tell where is the problem with this code ?
Upvotes: 1
Views: 2011
Reputation: 1
You are writing
int* count = 0;
which would assign 0 to the address.
If you want to assign the value 0 to the value at address count, do this instead
int* count = new int;
*count = 0;
Upvotes: 0
Reputation: 2130
To leave the matter entirely understandable I would like to quote the following sources.
C_Programming/POSIX_Reference/unistd.h/fork
When a fork() system call is issued, a copy of all the pages corresponding to the parent process is created, loaded into a separate memory location by the OS for the child process. But this is not needed in certain cases. Consider the case when a child executes an "exec" system call or exits very soon after the fork(). When the child is needed just to execute a command for the parent process, there is no need for copying the parent process' pages, since exec replaces the address space of the process which invoked it with the command to be executed.
In such cases, a technique called copy-on-write (COW) is used. With this technique, when a fork occurs, the parent process's pages are not copied for the child process. Instead, the pages are shared between the child and the parent process. Whenever a process (parent or child) modifies a page, a separate copy of that particular page alone is made for that process (parent or child) which performed the modification. This process will then use the newly copied page rather than the shared one in all future references. The other process (the one which did not modify the shared page) continues to use the original copy of the page (which is now no longer shared). This technique is called copy-on-write since the page is copied when some process writes to it.
Also, to understand why these programs appear to be using the same space of memory (which is not the case), I would like to quote a part of the book "Operating Systems: Principles and Practice".
Most modern processors introduce a level of indirection, called virtual addresses. With virtual addresses, every process's memory starts at the "same" place, e.g., zero. Each process thinks that it has the entire machine to itself, although obviously that is not the case in reality.
So these virtual addresses are translations of physical addresses and doesn't represent the same physical memory space, to leave a more practical example we can do a test, if we compile and run multiple times a program that displays the direction of a static variable, such as this program.
#include <stdio.h>
int main() {
static int a = 0;
printf("%p\n", &a);
getchar();
return 0;
}
It would be impossible to obtain the same memory address in two different programs if we deal with the physical memory directly, but the results obtained from running the program several times are these,
Upvotes: 2
Reputation: 121
Check the above page on the properties of the forked process/child. Note that some of them includes: state is copied, including open files, register state and all memory allocations.
What basically happens is that process including its stacks and locks are copied to a new address space. As R Sahu pointed out, the address appears to be the same but since each process has its own copy of virtual memory, the pointer is not pointing to the same location(or else if any process can write in any process' memory space, it will become a huge security and stability concern. More importantly, this is how the linux system works.)
What you are looking for is IPC solutions like message passing or shared memory.
A little off topic here: the creation of a new process involves forking a child from the parent in order to create the structure for image of other programs to be loaded onto it.
Upvotes: 1
Reputation: 16379
Processes can have a single variable ( or lots of them) in a shared memory segment. There needs to be a way to coordinate access to the variable to avoid a race condition.
IF you want to implement this, try this for guidance:
http://beej.us/guide/bgipc/output/html/singlepage/bgipc.html
Upvotes: 1
Reputation: 206567
You asked:
Can you tell where is the problem with this code ?
There is a problem with the code but not where you think it is. Your understanding of how forked processes work is not quite right.
Each process gets its own copy of the process memory space. The address 1444711088
of the parent process is different from the address 1444711088
of the child process. They can hold values that vary independently.
Your code is subject to undefined behavior.
int* count = 0;
That initializes the pointer to 0
, which is not a valid address. Did you mean to use:
int count = 0;
instead?
Upvotes: 6