【问题标题】:How to make results of a thread operation visible to all other threads in a process?如何使线程操作的结果对进程中的所有其他线程可见?
【发布时间】:2013-11-15 10:57:14
【问题描述】:

这是我曾经意识到这不会发生的示例代码。我的目标是让父母看到孩子在struct ss 中对myint 所做的更改(在这个特定的示例中,我希望父母打印PARENT myint = 1,或者孩子设置的任何值)。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

struct ss {
  int myint;
};

int main(void) {
  int pid;
  struct ss *s = (struct ss *)malloc(sizeof(struct ss));
  s->myint = 0;
  if ((pid = fork()) < 0) return 1;
  switch (pid) {
    case -1: return 1;
    case 0:
      printf("CHILD address = %p\n", s);
      s->myint = 1;
      printf("CHILD myint = %d\n", s);
      printf("CHILD done.\n");
      // free(s);
      return 0;
    default:
      printf("PARENT address = %p\n", s);
      waitpid(pid, NULL, 0);
      printf("PARENT myint = %d\n", s->myint);
      printf("PARENT done.\n");
      break;
  }
  free(s);
  return 0;
}

这是我得到的输出之一:

PARENT address = 0x1a79010
CHILD address = 0x1a79010
CHILD myint = 1
CHILD done.
PARENT myint = 0
PARENT done.

TBH,这让我完全困惑:PARENT 和 CHILD 怎么有相同的地址,但显然,出于某种原因,父母看不到孩子写到这个地址的值?此外,我认为除了调用堆栈之外的所有内存都是在进程的线程之间共享的。我在这里忽略了一些微不足道的错误吗?

【问题讨论】:

  • 好吧,因为你没有使用线程!父子进程是不同的进程,所以当子进程写入该地址时,内核会复制内存页,从而得到一个私有副本,并将其映射到同一个地址的子进程中读写。
  • 所以当孩子开始使用它时(在典型的实现中),父母和孩子中的(相同的)地址被映射到不同的RAM。

标签: c multithreading fork


【解决方案1】:

fork() 不会启动新线程,它会克隆整个进程。所以在fork() 之后,你有两个具有相同内存的进程,所以变量地址是相同的。

【讨论】:

    【解决方案2】:

    正如威利斯所说。如果您想实现您的目标,您可能需要使用 POSIX pthread 来创建线程。

    【讨论】:

      【解决方案3】:

      我已经在另一个主题中回答过,这是我的回答: 您正在使用 fork()。它创建了一个与您的实际进程完全相同的进程,但它不共享相同的内存。如果您使用线程,所有内存寻址都将被共享,您需要同步对共享内存位置的访问以满足数据的一致性。

      【讨论】:

        猜你喜欢
        • 2016-04-16
        • 1970-01-01
        • 2019-02-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-01
        相关资源
        最近更新 更多