我正在尝试编写一个允许三个线程访问/修改公共缓冲区的程序。我全局声明缓冲区,并在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;
}
答案 0 :(得分:3)
如果您fork()
,则不会创建新线程,而是创建程序的新实例。内存区域不在实例之间共享,而是在所有实例中重复。您需要的是pthread_create
或类似的。另外,信号量不是线程互斥的正确机制,你真正想要的是一个互斥体。
编辑:这并不是说进程之间无法共享内存。存在共享内存的可能性,但是malloc()
不会返回这样的内存块。如果您想在进程之间共享内存,请查看mmap
的主页,尤其是有关MAP_SHARED
的部分。但是,请注意,您还必须在实例之间共享同步原语。每个进程的堆栈上的本地进程不会在实例之间同步任何内容。