线程访问/更新共享内存位置

时间:2014-03-03 17:10:16

标签: c multithreading

我正在尝试编写一个允许三个线程访问/修改公共缓冲区的程序。我全局声明缓冲区,并在main()函数的开头调用malloc。然后我通过fork()创建不同的线程。信号量用于确保一次只能访问/更新缓冲区。我感到困惑的是,其他线程对缓冲区的更改没有被单个线程拾取。我打印出每个线程中缓冲区内存中的位置,并且它们对所有线程都是相同的。不会更新它跨越所有线程吗?我的印象是线程共享相同的资源/地址空间?

#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;
}

1 个答案:

答案 0 :(得分:3)

如果您fork(),则不会创建新线程,而是创建程序的新实例。内存区域不在实例之间共享,而是在所有实例中重复。您需要的是pthread_create或类似的。另外,信号量不是线程互斥的正确机制,你真正想要的是一个互斥体。

编辑:这并不是说进程之间无法共享内存。存在共享内存的可能性,但是malloc()不会返回这样的内存块。如果您想在进程之间共享内存,请查看mmap的主页,尤其是有关MAP_SHARED的部分。但是,请注意,您还必须在实例之间共享同步原语。每个进程的堆栈上的本地进程不会在实例之间同步任何内容。