简体   繁体   English

关于fork系统调用和全局变量

[英]About fork system call and global variables

I have this program in C++ that forks two new processes: 我在C ++中有这个程序,它有两个新进程:

#include <pthread.h>
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <cstdlib>
using namespace std;

int shared;

void func(){
  extern int shared;
  for (int i=0; i<10;i++)
        shared++;
  cout<<"Process "<<getpid()<<", shared "
        <<shared<<", &shared "
        <<&shared<<endl;
}

int main(){
  extern int shared;
  pid_t p1,p2;
  int status;
  shared=0;
  if ((p1=fork())==0) {func();exit(0);};
  if ((p2=fork())==0) {func();exit(0);};
  for(int i=0;i<10;i++)
        shared++;
  waitpid(p1,&status,0);
  waitpid(p2,&status,0);;
  cout<<"shared variable is: "<<shared<<endl;
  cout<<"Process "<<getpid()<<", shared "
        <<shared<<", &shared "
        <<&shared<<endl;
}

The two forked processes make an increment on the shared variables and the parent process does the same. 两个分叉进程对共享变量进行增量,父进程执行相同操作。 As the variable belongs to the data segment of each process, the final value is 10 because the increment is independent. 由于变量属于每个进程的数据段,因此最终值为10,因为增量是独立的。

However, the memory address of the shared variables is the same, you can try compiling and watching the output of the program. 但是,共享变量的内存地址是相同的,您可以尝试编译并观察程序的输出。 How can that be explained ? 怎么解释? I cannot understand that, I thought I knew how the fork() works, but this seems very odd.. 我无法理解,我以为我知道fork()是如何工作的,但这看起来很奇怪..

I need an explanation on why the address is the same, although they are separate variables. 我需要解释为什么地址是相同的,尽管它们是单独的变量。

The OS is using virtual memory and similar techniques to ensure that each process sees different memory cells (virtual or read) at the same addresses; 操作系统正在使用虚拟内存和类似技术来确保每个进程在同一地址看到不同的内存单元(虚拟或读取); only memory that's explicitly shared (eg via shm) is shared, all memory by default is separate among separate processes. 只共享显式共享的内存(例如通过shm),默认情况下所有内存在不同进程之间是分开的。

This is called "virtual address". 这称为“虚拟地址”。 Each process has its own address space, and each address means something different, depending on the process. 每个进程都有自己的地址空间,每个地址都意味着不同的东西,具体取决于进程。 fork() creates a copy, instead of sharing data (technically, they may get shared copy-on-write, but this is has the same effect as upfront copying would). fork()创建一个副本,而不是共享数据(从技术上讲,它们可能会在写入时进行共享拷贝,但这与前期复制具有相同的效果)。 IOW, the variable "shared" is not shared between processes. IOW,变量“shared”不在进程之间共享。

Pointers on modern systems doesn't correspond to actual hardware memory addresses. 现代系统上的指针与实际硬件存储器地址不对应。 Rather the addresses maps to a virtual space managed by the operating system. 而是地址映射到由操作系统管理的虚拟空间。 Therefore the pointer addresses for two different processes can appear to be the same when they in reality are not. 因此,当它们实际上不是时,两个不同进程的指针地址可能看起来是相同的。

Does this apply to pthread_mutex objects also. 这是否也适用于pthread_mutex对象。 Say I have mutex in the parent that gets locked and unlocked in a particular function. 假设我在父项中有互斥锁,在某个特定函数中被锁定和解锁。 Now the parent creates a child process. 现在,父级创建子进程。 Both parent and child can call this function simultaneously (Parent not really blocked till child exits as parent is a multi-threaded program, the thread that spawns child is only one blocked). 父级和子级都可以同时调用此函数(父级不会被阻塞直到子级退出,因为父级是多线程程序,生成子级的线程只有一个被阻止)。 So is the mutex object state - shared between the 2 processes? 互斥对象状态也是如此 - 在两个进程之间共享? If in parent, mutex was locked then child was created child gets to run first child sees the mutex in locked state as it has just inherited the mutex object as it is from parent now child unlocks mutex How is the state of this mutex in parent now - still locked (because parent never unlocked) or Unlocked because child has unlocked it. 如果在父项中,则互斥锁被锁定然后子项被创建子项运行第一个孩子看到互斥锁处于锁定状态,因为它刚刚继承了互斥对象,因为它来自父项现在子项解锁互斥体现在这个互斥体在父项中的状态如何? - 仍然锁定(因为父母从未解锁)或解锁,因为孩子已解锁它。

Is it ok to call such a function that locks/unlocks global mutexes from parent and child? 是否可以调用这样一个函数来锁定/解锁来自父和子的全局互斥?

是的,你认为是正确的,但为了节省一些内存,内部页面在父和子之间共享,直到子进行exec系统调用或修改任何变量或数据结构。因为许多页面之间共享父级和子级.....如果页面被子级修改,那么该页面将被复制到单独的内存区域并将被分配给子级。如果它被父级修改,那么该页面将被复制到单独的内存区域并分配给父母

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM