简体   繁体   English

在QNX中使用fork()时如何确保子进程和父进程具有不同的地址空间

[英]How to ensure child and parent processes have different address space when using fork() in QNX

The question is particulary about QNX and pretty much stated in the title. 这个问题特别是关于QNX的,标题中也有很多说明。 I tried logging the variable addresses after modifying them in both processes, assuming copy-on-write doesn't work anymore and they are not identical, so I expected the addresses to be different. 我在两个过程中都对变量地址进行了修改之后,尝试记录日志,假设“写时复制”不再起作用,并且它们也不相同,因此我希望这些地址不同。 But they are the same (virtual addresses, but still). 但是它们是相同的(虚拟地址,但仍然)。

So how can I check that one process doesn't affect another without printing variables value, maybe there's a simpler solution? 因此,如何在不打印变量值的情况下检查一个过程是否不会影响另一个过程,也许有一个更简单的解决方案?

int q;
q = 3;
...
if (pid == 0) {
    // in child
    q = 5;
    printf("%d\n", &q);
} else {
    // in parent
    q = 9;
    printf("%d\n", &q);
}

The virtual addresses you print will be identical — the child process is an almost exact copy of its parent. 您打印的虚拟地址将是相同的–子进程几乎是其父进程的完全相同的副本。 The physical addresses the programs access will be separate as soon as one process tries to modify the data in that page, but that will be completely hidden from the two processes. 一旦一个进程试图修改该页面中的数据,程序访问的物理地址将是分开的,但是这两个进程将完全隐藏它们。 That's the beauty of virtual memory. 那就是虚拟内存的美。

Note that you're using the wrong format for printing addresses; 请注意,您使用错误的格式来打印地址。 you should use %p and cast the address to void * : 您应该使用%p并将地址强制转换为void *

printf("%p\n", (void *)&q);

or use <inttypes.h> and uintptr_t and PRIXPTR (or PRIdPTR is you really want the address in decimal rather than hex): 或使用<inttypes.h>uintptr_tPRIXPTR (或PRIdPTR是您真的想要十进制而不是十六进制的地址):

printf("0x%" PRIXPTR "\n", (uintptr_t)&q);

Print the numbers too — and do so several times in a loop with sleeps of some sort in them. 也打印数字-并循环进行几次,并进行某种形式的睡眠。 You will see that despite the same logical (virtual) address, the physical addresses are different. 您将看到,尽管逻辑(虚拟)地址相同,但物理地址却不同。 You won't be able to find the physical address easily, though. 但是,您将无法轻松找到物理地址。

If you have created a new process, rather than a new thread, then it has its own process address space by definition. 如果您创建的是新进程,而不是新线程,那么根据定义,它具有自己的进程地址空间。

Every process address space will have the same virtual address range - 0x00000000 - 0xffffffff on a 32-bit machine. 在32位计算机上,每个进程地址空间将具有相同的虚拟地址范围0x00000000 - 0xffffffff Every process will have a virtual address of n , what it is used for and whether it maps to anything which physically exists will differ. 每个进程都有一个虚拟地址n ,它的用途以及它是否映射到实际存在的任何东西都将有所不同。 Some of that address space will be used by the kernel, some might be shared (see also man mmap ). 某些地址空间将由内核使用,而某些地址空间可能会被共享(另请参阅man mmap )。

After a fork() you should not be surprised if the virtual addresses are identical in both processes (although that cannot be guaranteed for new memory operations after the fork ) - it does not mean that copy-on-write is not working, that is invisible to normal code. fork()之后,如果两个进程中的虚拟地址都相同(尽管不能保证fork之后的新内存操作),则不要感到惊讶-这并不意味着写时复制不起作用,也就是说普通代码不可见。

Pages do not necessarily reside in RAM (physical memory) but can sit in a swap or paging file (terms used vary) until required. 页面不一定位于RAM(物理内存)中,而是可以位于交换文件或页面文件中(使用的术语有所不同),直到需要为止。 The virtual address refers to a page table that knows where its page really lives. 虚拟地址是指一个页面表,该表知道其页面的实际位置。 When copy-on-write kicks in it means a new page is created, it does not mean that the virtual address changes, it will stay the same but in the page table will refer to a different physical location. 写入时启动复制意味着它创建了一个新页面,但这并不意味着虚拟地址已更改,它将保持不变,但在页面表中将引用不同的物理位置。

Why would you want to know anyway? 您为什么仍然想知道? That kind of operation is in the domain of the operating system. 这种操作属于操作系统的范围。

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

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