Danzo
Danzo

Reputation: 553

Threads accessing/updating a shared memory location

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

Answers (1)

JustSid
JustSid

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

Related Questions