How to share memory between processes created by fork()?
86,994
Solution 1
You can use shared memory (shm_open()
, shm_unlink()
, mmap()
, etc.).
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
static int *glob_var;
int main(void)
{
glob_var = mmap(NULL, sizeof *glob_var, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
*glob_var = 1;
if (fork() == 0) {
*glob_var = 5;
exit(EXIT_SUCCESS);
} else {
wait(NULL);
printf("%d\n", *glob_var);
munmap(glob_var, sizeof *glob_var);
}
return 0;
}
Solution 2
Changing a global variable is not possible because the new created process (child)is having it's own address space.
So it's better to use shmget()
,shmat()
from POSIX
api
Or You can use pthread
, since pthreads
are sharing the global
data and the changes in global variable is reflected in parent.
Then read some Pthreads tutorial.
Solution 3
Here is an alternative solution.
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
typedef struct
{
int id;
size_t size;
} shm_t;
shm_t *shm_new(size_t size)
{
shm_t *shm = calloc(1, sizeof *shm);
shm->size = size;
if ((shm->id = shmget(IPC_PRIVATE, size, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) < 0)
{
perror("shmget");
free(shm);
return NULL;
}
return shm;
}
void shm_write(shm_t *shm, void *data)
{
void *shm_data;
if ((shm_data = shmat(shm->id, NULL, 0)) == (void *) -1)
{
perror("write");
return;
}
memcpy(shm_data, data, shm->size);
shmdt(shm_data);
}
void shm_read(void *data, shm_t *shm)
{
void *shm_data;
if ((shm_data = shmat(shm->id, NULL, 0)) == (void *) -1)
{
perror("read");
return;
}
memcpy(data, shm_data, shm->size);
shmdt(shm_data);
}
void shm_del(shm_t *shm)
{
shmctl(shm->id, IPC_RMID, 0);
free(shm);
}
int main()
{
int var = 1;
shm_t *shm = shm_new(sizeof var);
int pid;
if ((pid = fork()) == 0)
{ /* child */
var = 5;
shm_write(shm, &var);
printf("child: %d\n", var);
return 0;
}
/* Wait for child to return */
int status;
while (wait(&status) != pid);
/* */
shm_read(&var, shm);
/* Parent is updated by child */
printf("parent: %d\n", var);
shm_del(shm);
return 0;
}
Build with:
$ gcc shm.c -o shm && ./shm
Comments
-
MOHAMED almost 2 years
In fork child, if we modify a global variable, it will not get changed in the main program.
Is there a way to change a global variable in child fork?
#include <stdio.h> #include <stdlib.h> #include <unistd.h> int glob_var; main (int ac, char **av) { int pid; glob_var = 1; if ((pid = fork()) == 0) { /* child */ glob_var = 5; } else { /* Error */ perror ("fork"); exit (1); } int status; while (wait(&status) != pid) { } printf("%d\n",glob_var); // this will display 1 and not 5. }
-
MOHAMED over 11 yearscould you provide a simple example
-
Grambot over 11 yearsYou'll need to look up shared memory; lots of examples on google. This allows two separate applications to use the same memory to store and read variables. When you
fork()
a process it creates a child process with a separate memory heap from the parent. Your parent will maintain its global variables while the child will allocate its own copies. -
iabdalkader over 11 yearsYou can find some examples with a very good explanation here
-
TheLoneJoker almost 10 years@md5: In the mmap function call the file descriptor handle is "-1". What does -1 signify ?
-
D3Hunter over 9 years@TheLoneJoker. From man page of
mmap
:however, some implementations require fd to be -1 if MAP_ANONYMOUS (or MAP_ANON) is specified, and portable applications should ensure this