Reputation: 553
I'm attempting to write a program that allows three threads to access/modify a common buffer. I declare the buffer globally, and call malloc in the beginning of my main() function. I then create the different threads via fork(). A semaphore is used to make sure only one can access/update the buffer at one time. What I am confused about is, changes to the buffer by other threads aren't being picked up by a singular thread. I print out the location in memory of buffer in each thread, and its the same for all of them. Wouldn't updating it carry over across all the threads? I was under the impression threads share the same resources/address space?
#define buf_size 100
char *buffer;
int main(int argc, char *argv[])
{
sem_t sp;
(sem_init(&sp,1,1));
buffer= malloc(100);
pid_t p2_pid; // child PID
if ((p2_pid = fork()) < 0)
{
err_sys("fork error (1)");
}
else if (p2_pid > 0) // this is the parent (P1)
{
int i = 0;
sem_wait(&sp);
printf("Process 1 accessing buffer\n");
printf("BufAddr: %d\n", (buffer));
for(i=0; i < 50; i++)
{
if(i%2==0)
{
buffer[i] = 'c';
}
else
{
buffer[i] = 'j';
}
printf("%c",(buffer[i]));
}
printf("\n");
sem_post(&sp);
if (waitpid(p2_pid, NULL, 0) < 0) // wait for child (P2)
{ err_sys("waitpid error (1)"); }
}
else // this is the child (P2)
{
pid_t p3_pid;
if ((p3_pid = fork()) < 0)
{
err_sys("fork error (2)");
}
else if (p3_pid > 0)
{
int j = 0;
sem_wait(&sp);
printf("Process 2 accessing buffer\n");
printf("BufAddr: %d\n", (buffer));
for(j=0; j < 50; j++)
{
if(buffer[j]=='c')
{
buffer[j] = 'b';
}
else
{
buffer[j] = 'g';
}
printf("%c",(buffer[j]));
}
printf("\n");
sem_post(&sp);
if (waitpid(p3_pid, NULL, 0) < 0)
{ err_sys("waitpid error (2)"); }
}
else
{
int k = 0;
int bCount = 0;
int gCount = 0;
sem_wait(&sp);
printf("Process 3 accessing buffer\n");
printf("BufAddr: %d\n", (buffer));
for(k=0; k < 50; k++)
{
if(buffer[k]=='g')
{
gCount++;
}
else
{
bCount++;
}
printf("%c",(buffer[k]));
}
sem_post(&sp);
printf("bCount = %d\n" , (bCount));
printf("gCount = %d\n" , (gCount));
}
}
return 0;
}
Upvotes: 1
Views: 174
Reputation: 25318
If you fork()
, you don't create a new thread but a new instance of your program. The memory region isn't shared between the instances, but instead is duplicated in all of them. What you need is pthread_create
or similar. Also, a semaphore is not the right mechanism for mutual exclusion of threads, what you really want for this is a mutex.
Edit: That is not to say that memory can't be shared between processes. There is the possibility of shared memory, however, malloc()
won't return such a memory block. If you want to share memory between processes, check out the main page for mmap
and especially the section about MAP_SHARED
. However, also note that you additionally have to share your synchronization primitive between the instances. A local one on the stack of each process won't synchronize anything between the instances.
Upvotes: 3