Reputation: 549
I have the following main.c:
#include <unistd.h> //has thread calls for fork()
#include <stdio.h>
struct globalInfo{
int x;
};
int do this()
{
info.x++;
printf("%d\n",info.x);
return 0;
}
int main{
struct globalInfo info = { .x = 2};
for(int i = 0 ; i < 5 ; i++)
{
if(fork() = 0)
{
dothis();
}
}
}
This isn't my exact code, but my question is more easily demonstrated here.
Now the output for the above function is:
3
3
3
3
3
What I want is:
3
4
5
6
7
How do share this struct between threads? It seems like every thread is just creating its own copy of the struct and manipulating its own copy. I've tried to pass a pointer to the info struct as a parameter to dothis()
, but that doesn't fix it either. I've also tried placing the info initialization out of the main; that didn't work either..
Help would be greatly appreciated.
Upvotes: 1
Views: 4886
Reputation: 2289
As people have already noted you are creating processes not threads. Sharing data among processes is harder. Every process has its own memory address space which means that they may share same code, but their data is private.
There are several techniques if you want to have shared data among processes. One of them is shared memory with memory map
#include <unistd.h> //has thread calls for fork()
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
struct globalInfo{
int x;
};
char *shm = "/asd8"; // change this before every run to avoid error 22
int dothis()
{
// sleep(1); // helps to simulate race condition
int len = sizeof(struct globalInfo);
int fd = shm_open(shm, O_RDWR, 0);
void *addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (addr == MAP_FAILED){
perror(""); // error handling
}
struct globalInfo *info = (struct globalInfo *)addr;
info->x++;
printf("%d %d\n", info->x, getpid());
return 0;
}
int main(){
struct globalInfo info = { .x = 2};
int len = sizeof(struct globalInfo);
int fd = shm_open(shm, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (fd == -1)
perror(""); // error handling
if(ftruncate(fd, len) == -1){
printf("%d\n", errno); // osx produces error 22 don't know why
perror("");
}
void *addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
memcpy(addr, &info, len);
for(int i = 0 ; i < 5 ; i++)
{
if(fork() == 0)
{
dothis();
break;
}
}
}
sample output
3 30588
4 30589
6 30590
6 30591
7 30592
Also it would be great if you read chapters from The Linux Programming Interface: A Linux and UNIX System Programming Handbook
Upvotes: 0
Reputation: 1115
Use any IPC
to share data b/w processes
. In threads
the data can be shared by following methods:
pthread_exit
and catch in pthread_join
shared/global resource
of process accessed by synchronizing
methodsUpvotes: 0
Reputation: 3767
fork() doesnot create a thread it creates processes, processess will have different address spaces altogether hence data wil not be shared even if it is global data.
in case you are thinking of threads use pthreads incase you are looking for processes you need to use IPC mechanisms
Upvotes: 2