На самом деле тут два вопроса (но они связаны между собой).
Вопрос #1:
Никак не получается понять почему переменная которая была объявлена до вызова fork() (то есть в родительском процессе) имеет тот же адрес и в дочернем процессе. Хотя насколько мне известно дочерний процесс будет иметь своё виртуальное адресное пространство и соответственно (как я понимаю) та переменная должна иметь другой адрес, но это не так. Тем не менее, всё работает так как будто они действительно изолированы друг от друга (изменения в дочернем не видны в родительском)
Вопрос #2:
Почему при использовании munmap() в дочернем процессе (перед его завершением), в родительском процессе всё ещё можно получать доступ и изменять содержимое "маппнутой" памяти??? (Есть догадка, что это будет связано с ответом на первый вопрос).
Код программы:
#include <iostream>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/wait.h>
int main(int argc, char* argv[])
{
void* shared = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
int* sharedValue = static_cast<int*>(shared);
*sharedValue = 0;
std::cout << "before forks sharedValue: " << sharedValue << '\n';
std::cout << "before forks *sharedValue: " << *sharedValue << '\n';
int value = 0;
std::cout << "before forks &value: " << &value << '\n';
std::cout << "before forks value: " << value << '\n';
int parentpid = getpid();
int childpid;
for(int i = 0; i < 2; ++i)
{
int forkret = fork();
switch (forkret)
{
case -1:
std::cerr << "Fork failed...\n";
exit(EXIT_FAILURE);
case 0:
childpid = getpid();
std::cout << "Child: pid " << childpid << '\n';
std::cout << "child &value: " << &value << '\n';
std::cout << "child value: " << value << '\n';
std::cout << "child sharedValue: " << sharedValue << '\n';
std::cout << "child *sharedValue: " << *sharedValue << '\n';
value = childpid;
*sharedValue = childpid;
std::cout << "child value = pid: " << value << '\n';
std::cout << "child *sharedValue = pid: " << value << '\n';
munmap(sharedValue, sizeof(int));
std::cout << "child munmap() called\n";
exit(EXIT_SUCCESS);
default:
std::cout << "Parent: pid " << parentpid << '\n';
wait(0);
std::cout << "Child terminated\n";
std::cout << "parent &value: " << &value << '\n';
std::cout << "parent value: " << value << '\n';
std::cout << "parent sharedValue: " << sharedValue << '\n';
std::cout << "parent *sharedValue: " << *sharedValue << '\n';
value = parentpid;
*sharedValue = parentpid;
std::cout << "parent value = pid: " << value << '\n';
std::cout << "parent *sharedValue = pid: " << value << '\n';
}
}
std::cout << "Parent terminated\n";
return 0;
}
Вывод в консоли:
before forks sharedValue: 0x7ffff7ffb000
before forks *sharedValue: 0
before forks &value: 0x7fffffffdc74
before forks value: 0
Parent: pid 18027
Child: pid 18034
child &value: 0x7fffffffdc74
child value: 0
child sharedValue: 0x7ffff7ffb000
child *sharedValue: 0
child value = pid: 18034
child *sharedValue = pid: 18034
child munmap() called
Child terminated
parent &value: 0x7fffffffdc74
parent value: 0
parent sharedValue: 0x7ffff7ffb000
parent *sharedValue: 18034
parent value = pid: 18027
parent *sharedValue = pid: 18027
Parent: pid 18027
Child: pid 18035
child &value: 0x7fffffffdc74
child value: 18027
child sharedValue: 0x7ffff7ffb000
child *sharedValue: 18027
child value = pid: 18035
child *sharedValue = pid: 18035
child munmap() called
Child terminated
parent &value: 0x7fffffffdc74
parent value: 18027
parent sharedValue: 0x7ffff7ffb000
parent *sharedValue: 18035
parent value = pid: 18027
parent *sharedValue = pid: 18027
Parent terminated