Child Processes memory allocation and the purpose of reaping child processes
I'm a beginner in processes, still struggling to understand the purpose of reaping child processes and memory allocation for them, so my questions are:
Q1. Why Linux doesn't have a mechanism of auto reaping child processes, I mean all child processes are terminated and removed once they finished just like garbage collection, so that users don't need to use waitpid
to manually reap child processes?
Q2. my textbooks says that when users use fork() to create a new child process, the child gets an identical (but separate) copy of the parent’s text, data, and bss segments, heap, and user stack. So does it mean that same size of memory address of parents is allocated to the child as well and the memory content of child is exact then same as its parent? if so, lets say we create a huge number of child processes, isn't that the stack will overflow very easily?
Q3. Lets say the picture below is a parent processes
and you can see the user stack highlighted in red is the stack of the parent. So if the parent program uses fork() and when it executes fork() function, how does child processes' stack get allocated? is the child stack next to current stack
c linux process operating-system
add a comment |
I'm a beginner in processes, still struggling to understand the purpose of reaping child processes and memory allocation for them, so my questions are:
Q1. Why Linux doesn't have a mechanism of auto reaping child processes, I mean all child processes are terminated and removed once they finished just like garbage collection, so that users don't need to use waitpid
to manually reap child processes?
Q2. my textbooks says that when users use fork() to create a new child process, the child gets an identical (but separate) copy of the parent’s text, data, and bss segments, heap, and user stack. So does it mean that same size of memory address of parents is allocated to the child as well and the memory content of child is exact then same as its parent? if so, lets say we create a huge number of child processes, isn't that the stack will overflow very easily?
Q3. Lets say the picture below is a parent processes
and you can see the user stack highlighted in red is the stack of the parent. So if the parent program uses fork() and when it executes fork() function, how does child processes' stack get allocated? is the child stack next to current stack
c linux process operating-system
For Q1: Consider a parent process forking a child process. When the child process terminates, the OS continues to store information about the return status of the child process so that when the parent calls waitpid it can get the return status. Only after the parent calls waitpid, can the OS can reap the child process.
– MFisherKDX
Nov 14 '18 at 1:21
@MFisherKDX so is the purpose of reaping child processes is just to get return statuses of child processes?
– amjad
Nov 14 '18 at 1:27
Have a read here: Zombie Process
– MFisherKDX
Nov 14 '18 at 1:33
add a comment |
I'm a beginner in processes, still struggling to understand the purpose of reaping child processes and memory allocation for them, so my questions are:
Q1. Why Linux doesn't have a mechanism of auto reaping child processes, I mean all child processes are terminated and removed once they finished just like garbage collection, so that users don't need to use waitpid
to manually reap child processes?
Q2. my textbooks says that when users use fork() to create a new child process, the child gets an identical (but separate) copy of the parent’s text, data, and bss segments, heap, and user stack. So does it mean that same size of memory address of parents is allocated to the child as well and the memory content of child is exact then same as its parent? if so, lets say we create a huge number of child processes, isn't that the stack will overflow very easily?
Q3. Lets say the picture below is a parent processes
and you can see the user stack highlighted in red is the stack of the parent. So if the parent program uses fork() and when it executes fork() function, how does child processes' stack get allocated? is the child stack next to current stack
c linux process operating-system
I'm a beginner in processes, still struggling to understand the purpose of reaping child processes and memory allocation for them, so my questions are:
Q1. Why Linux doesn't have a mechanism of auto reaping child processes, I mean all child processes are terminated and removed once they finished just like garbage collection, so that users don't need to use waitpid
to manually reap child processes?
Q2. my textbooks says that when users use fork() to create a new child process, the child gets an identical (but separate) copy of the parent’s text, data, and bss segments, heap, and user stack. So does it mean that same size of memory address of parents is allocated to the child as well and the memory content of child is exact then same as its parent? if so, lets say we create a huge number of child processes, isn't that the stack will overflow very easily?
Q3. Lets say the picture below is a parent processes
and you can see the user stack highlighted in red is the stack of the parent. So if the parent program uses fork() and when it executes fork() function, how does child processes' stack get allocated? is the child stack next to current stack
c linux process operating-system
c linux process operating-system
edited Nov 14 '18 at 1:24
amjad
asked Nov 14 '18 at 1:15
amjadamjad
4079
4079
For Q1: Consider a parent process forking a child process. When the child process terminates, the OS continues to store information about the return status of the child process so that when the parent calls waitpid it can get the return status. Only after the parent calls waitpid, can the OS can reap the child process.
– MFisherKDX
Nov 14 '18 at 1:21
@MFisherKDX so is the purpose of reaping child processes is just to get return statuses of child processes?
– amjad
Nov 14 '18 at 1:27
Have a read here: Zombie Process
– MFisherKDX
Nov 14 '18 at 1:33
add a comment |
For Q1: Consider a parent process forking a child process. When the child process terminates, the OS continues to store information about the return status of the child process so that when the parent calls waitpid it can get the return status. Only after the parent calls waitpid, can the OS can reap the child process.
– MFisherKDX
Nov 14 '18 at 1:21
@MFisherKDX so is the purpose of reaping child processes is just to get return statuses of child processes?
– amjad
Nov 14 '18 at 1:27
Have a read here: Zombie Process
– MFisherKDX
Nov 14 '18 at 1:33
For Q1: Consider a parent process forking a child process. When the child process terminates, the OS continues to store information about the return status of the child process so that when the parent calls waitpid it can get the return status. Only after the parent calls waitpid, can the OS can reap the child process.
– MFisherKDX
Nov 14 '18 at 1:21
For Q1: Consider a parent process forking a child process. When the child process terminates, the OS continues to store information about the return status of the child process so that when the parent calls waitpid it can get the return status. Only after the parent calls waitpid, can the OS can reap the child process.
– MFisherKDX
Nov 14 '18 at 1:21
@MFisherKDX so is the purpose of reaping child processes is just to get return statuses of child processes?
– amjad
Nov 14 '18 at 1:27
@MFisherKDX so is the purpose of reaping child processes is just to get return statuses of child processes?
– amjad
Nov 14 '18 at 1:27
Have a read here: Zombie Process
– MFisherKDX
Nov 14 '18 at 1:33
Have a read here: Zombie Process
– MFisherKDX
Nov 14 '18 at 1:33
add a comment |
2 Answers
2
active
oldest
votes
Q1. Why Linux doesn't have a mechanism of auto reaping child processes, I mean all child processes are terminated and removed once they finished just like garbage collection, so that users don't need to use waitpid to manually reap child processes?
It does. Just set SIGCHLD to be ignored and your children will be reaped for you.
Q2. my textbooks says that when users use fork() to create a new child process, the child gets an identical (but separate) copy of the parent’s text, data, and bss segments, heap, and user stack. So does it mean that same size of memory address of parents is allocated to the child as well and the memory content of child is exact then same as its parent?
That's an implementation detail. Most modern systems just share the memory between the two processes.
if so, lets say we create a huge number of child processes, isn't that the stack will overflow very easily?
No. The stack overflows when you run out of address space in a particular process' view of memory. Since each fork
creates a new process, you aren't going to run out of address space in any particular process.
Q3. Lets say the picture below is a parent processes enter image description here
... and you can see the user stack highlighted in red is the stack of the parent. So if the parent program uses fork() and when it executes fork() function, how does child processes' stack get allocated? is the child stack next to current stack?
The child process' stack is in another process. So if that's the address space for the parent process' segments, the child process' stack isn't in it at all. The child process begins with a copy of the parent's address space -- typically with the actual memory pages shared, at least until either process tries to modify them (which unshares them).
Could you also take a look at this question, please? stackoverflow.com/questions/53626179/…
– amjad
Dec 5 '18 at 6:18
add a comment |
Although David Schwartz already answered the stated questions, I'd like to talk about the underlying picture. So, do not consider this an answer, but an extended comment.
The problem is, the image shown is not a good representation of the address space a normal userspace application sees on current computers and operating systems.
Each process has their own address space. This is implemented using virtual memory; a mapping from virtual addresses to actual hardware accesses that is for all intents and purposes invisible to the userspace process. (Virtual memory is not per-address, but uses smallish chunks called pages. On all current architectures, each page is a power of two bytes in size. 212 = 4096 is common, but other sizes like 216 = 65536 and 221 = 2097152 are also used.)
Even when you use shared memory, it can reside at different virtual addresses for different processes. (This is also the reason you cannot really use pointers in shared memory.)
When a process is fork()ed, the virtual memory is cloned. (It is not really copied per se, as that would waste resources. Usually a technique called copy-on-write is used by the OS kernel, so that the actual same physical RAM is used for memory used by both/all processes, until one of them modifies their "copy"; at which point the OS kernel detaches the affected page duplicating its contents, before allowing the modifiaction to proceed.)
This means that after a fork(), the parent and child processes will have their stacks at exactly the same virtual addresses.
The only limit is how much actual RAM there is available. Actually, the OS kernel can also move currently unused files to swap or paging file; but if those pages end up being needed soon, it slows down the operation of the machine. On Linux at least, binaries and libraries also get directly mapped to their respective files -- that being the reason why you can't modify executable files when they are in use --, so unless the RAM copy of the code is modified, they tend to not use swap/paging file.
In most cases, some of the virtual memory range is reserved for the OS kernel. It does not mean that the kernel memory is visible to userspace, or accessible in any way; it is just a way to ensure that when transferring data to or from userspace processes, the OS kernel can use the userspace virtual memory addresses, and not mix them with its own internal addresses. Essentially, the OS kernel just won't create any virtual memory mappings to addresses it uses itself, for any userspace process, to make its own job simpler.
An interesting detail on Linux is that typically, the default stack size for new threads is rather large, 8 MiB (8,388,608 bytes) on 32-bit x86. Unless you set a smaller stack, the number of threads a process can create is limited by the available virtual memory. Each userspace process can use the lower 3 GiB, or virtual memory addresses below 3,221,225,472 on 32-bit x86; and you can fit at most 384 8 MiB stacks in that. If you account for the standard libraries and so on, typically on those systems a process can create about 300 threads, before it runs out virtual memory. If you use a much smaller stack, say 65536 bytes, a process can create thousands of threads even on 32-bit x86. Just remember that the issue there is running out of usable virtual memory address space, not memory per se.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53291801%2fchild-processes-memory-allocation-and-the-purpose-of-reaping-child-processes%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Q1. Why Linux doesn't have a mechanism of auto reaping child processes, I mean all child processes are terminated and removed once they finished just like garbage collection, so that users don't need to use waitpid to manually reap child processes?
It does. Just set SIGCHLD to be ignored and your children will be reaped for you.
Q2. my textbooks says that when users use fork() to create a new child process, the child gets an identical (but separate) copy of the parent’s text, data, and bss segments, heap, and user stack. So does it mean that same size of memory address of parents is allocated to the child as well and the memory content of child is exact then same as its parent?
That's an implementation detail. Most modern systems just share the memory between the two processes.
if so, lets say we create a huge number of child processes, isn't that the stack will overflow very easily?
No. The stack overflows when you run out of address space in a particular process' view of memory. Since each fork
creates a new process, you aren't going to run out of address space in any particular process.
Q3. Lets say the picture below is a parent processes enter image description here
... and you can see the user stack highlighted in red is the stack of the parent. So if the parent program uses fork() and when it executes fork() function, how does child processes' stack get allocated? is the child stack next to current stack?
The child process' stack is in another process. So if that's the address space for the parent process' segments, the child process' stack isn't in it at all. The child process begins with a copy of the parent's address space -- typically with the actual memory pages shared, at least until either process tries to modify them (which unshares them).
Could you also take a look at this question, please? stackoverflow.com/questions/53626179/…
– amjad
Dec 5 '18 at 6:18
add a comment |
Q1. Why Linux doesn't have a mechanism of auto reaping child processes, I mean all child processes are terminated and removed once they finished just like garbage collection, so that users don't need to use waitpid to manually reap child processes?
It does. Just set SIGCHLD to be ignored and your children will be reaped for you.
Q2. my textbooks says that when users use fork() to create a new child process, the child gets an identical (but separate) copy of the parent’s text, data, and bss segments, heap, and user stack. So does it mean that same size of memory address of parents is allocated to the child as well and the memory content of child is exact then same as its parent?
That's an implementation detail. Most modern systems just share the memory between the two processes.
if so, lets say we create a huge number of child processes, isn't that the stack will overflow very easily?
No. The stack overflows when you run out of address space in a particular process' view of memory. Since each fork
creates a new process, you aren't going to run out of address space in any particular process.
Q3. Lets say the picture below is a parent processes enter image description here
... and you can see the user stack highlighted in red is the stack of the parent. So if the parent program uses fork() and when it executes fork() function, how does child processes' stack get allocated? is the child stack next to current stack?
The child process' stack is in another process. So if that's the address space for the parent process' segments, the child process' stack isn't in it at all. The child process begins with a copy of the parent's address space -- typically with the actual memory pages shared, at least until either process tries to modify them (which unshares them).
Could you also take a look at this question, please? stackoverflow.com/questions/53626179/…
– amjad
Dec 5 '18 at 6:18
add a comment |
Q1. Why Linux doesn't have a mechanism of auto reaping child processes, I mean all child processes are terminated and removed once they finished just like garbage collection, so that users don't need to use waitpid to manually reap child processes?
It does. Just set SIGCHLD to be ignored and your children will be reaped for you.
Q2. my textbooks says that when users use fork() to create a new child process, the child gets an identical (but separate) copy of the parent’s text, data, and bss segments, heap, and user stack. So does it mean that same size of memory address of parents is allocated to the child as well and the memory content of child is exact then same as its parent?
That's an implementation detail. Most modern systems just share the memory between the two processes.
if so, lets say we create a huge number of child processes, isn't that the stack will overflow very easily?
No. The stack overflows when you run out of address space in a particular process' view of memory. Since each fork
creates a new process, you aren't going to run out of address space in any particular process.
Q3. Lets say the picture below is a parent processes enter image description here
... and you can see the user stack highlighted in red is the stack of the parent. So if the parent program uses fork() and when it executes fork() function, how does child processes' stack get allocated? is the child stack next to current stack?
The child process' stack is in another process. So if that's the address space for the parent process' segments, the child process' stack isn't in it at all. The child process begins with a copy of the parent's address space -- typically with the actual memory pages shared, at least until either process tries to modify them (which unshares them).
Q1. Why Linux doesn't have a mechanism of auto reaping child processes, I mean all child processes are terminated and removed once they finished just like garbage collection, so that users don't need to use waitpid to manually reap child processes?
It does. Just set SIGCHLD to be ignored and your children will be reaped for you.
Q2. my textbooks says that when users use fork() to create a new child process, the child gets an identical (but separate) copy of the parent’s text, data, and bss segments, heap, and user stack. So does it mean that same size of memory address of parents is allocated to the child as well and the memory content of child is exact then same as its parent?
That's an implementation detail. Most modern systems just share the memory between the two processes.
if so, lets say we create a huge number of child processes, isn't that the stack will overflow very easily?
No. The stack overflows when you run out of address space in a particular process' view of memory. Since each fork
creates a new process, you aren't going to run out of address space in any particular process.
Q3. Lets say the picture below is a parent processes enter image description here
... and you can see the user stack highlighted in red is the stack of the parent. So if the parent program uses fork() and when it executes fork() function, how does child processes' stack get allocated? is the child stack next to current stack?
The child process' stack is in another process. So if that's the address space for the parent process' segments, the child process' stack isn't in it at all. The child process begins with a copy of the parent's address space -- typically with the actual memory pages shared, at least until either process tries to modify them (which unshares them).
answered Nov 14 '18 at 1:32
David SchwartzDavid Schwartz
137k14143224
137k14143224
Could you also take a look at this question, please? stackoverflow.com/questions/53626179/…
– amjad
Dec 5 '18 at 6:18
add a comment |
Could you also take a look at this question, please? stackoverflow.com/questions/53626179/…
– amjad
Dec 5 '18 at 6:18
Could you also take a look at this question, please? stackoverflow.com/questions/53626179/…
– amjad
Dec 5 '18 at 6:18
Could you also take a look at this question, please? stackoverflow.com/questions/53626179/…
– amjad
Dec 5 '18 at 6:18
add a comment |
Although David Schwartz already answered the stated questions, I'd like to talk about the underlying picture. So, do not consider this an answer, but an extended comment.
The problem is, the image shown is not a good representation of the address space a normal userspace application sees on current computers and operating systems.
Each process has their own address space. This is implemented using virtual memory; a mapping from virtual addresses to actual hardware accesses that is for all intents and purposes invisible to the userspace process. (Virtual memory is not per-address, but uses smallish chunks called pages. On all current architectures, each page is a power of two bytes in size. 212 = 4096 is common, but other sizes like 216 = 65536 and 221 = 2097152 are also used.)
Even when you use shared memory, it can reside at different virtual addresses for different processes. (This is also the reason you cannot really use pointers in shared memory.)
When a process is fork()ed, the virtual memory is cloned. (It is not really copied per se, as that would waste resources. Usually a technique called copy-on-write is used by the OS kernel, so that the actual same physical RAM is used for memory used by both/all processes, until one of them modifies their "copy"; at which point the OS kernel detaches the affected page duplicating its contents, before allowing the modifiaction to proceed.)
This means that after a fork(), the parent and child processes will have their stacks at exactly the same virtual addresses.
The only limit is how much actual RAM there is available. Actually, the OS kernel can also move currently unused files to swap or paging file; but if those pages end up being needed soon, it slows down the operation of the machine. On Linux at least, binaries and libraries also get directly mapped to their respective files -- that being the reason why you can't modify executable files when they are in use --, so unless the RAM copy of the code is modified, they tend to not use swap/paging file.
In most cases, some of the virtual memory range is reserved for the OS kernel. It does not mean that the kernel memory is visible to userspace, or accessible in any way; it is just a way to ensure that when transferring data to or from userspace processes, the OS kernel can use the userspace virtual memory addresses, and not mix them with its own internal addresses. Essentially, the OS kernel just won't create any virtual memory mappings to addresses it uses itself, for any userspace process, to make its own job simpler.
An interesting detail on Linux is that typically, the default stack size for new threads is rather large, 8 MiB (8,388,608 bytes) on 32-bit x86. Unless you set a smaller stack, the number of threads a process can create is limited by the available virtual memory. Each userspace process can use the lower 3 GiB, or virtual memory addresses below 3,221,225,472 on 32-bit x86; and you can fit at most 384 8 MiB stacks in that. If you account for the standard libraries and so on, typically on those systems a process can create about 300 threads, before it runs out virtual memory. If you use a much smaller stack, say 65536 bytes, a process can create thousands of threads even on 32-bit x86. Just remember that the issue there is running out of usable virtual memory address space, not memory per se.
add a comment |
Although David Schwartz already answered the stated questions, I'd like to talk about the underlying picture. So, do not consider this an answer, but an extended comment.
The problem is, the image shown is not a good representation of the address space a normal userspace application sees on current computers and operating systems.
Each process has their own address space. This is implemented using virtual memory; a mapping from virtual addresses to actual hardware accesses that is for all intents and purposes invisible to the userspace process. (Virtual memory is not per-address, but uses smallish chunks called pages. On all current architectures, each page is a power of two bytes in size. 212 = 4096 is common, but other sizes like 216 = 65536 and 221 = 2097152 are also used.)
Even when you use shared memory, it can reside at different virtual addresses for different processes. (This is also the reason you cannot really use pointers in shared memory.)
When a process is fork()ed, the virtual memory is cloned. (It is not really copied per se, as that would waste resources. Usually a technique called copy-on-write is used by the OS kernel, so that the actual same physical RAM is used for memory used by both/all processes, until one of them modifies their "copy"; at which point the OS kernel detaches the affected page duplicating its contents, before allowing the modifiaction to proceed.)
This means that after a fork(), the parent and child processes will have their stacks at exactly the same virtual addresses.
The only limit is how much actual RAM there is available. Actually, the OS kernel can also move currently unused files to swap or paging file; but if those pages end up being needed soon, it slows down the operation of the machine. On Linux at least, binaries and libraries also get directly mapped to their respective files -- that being the reason why you can't modify executable files when they are in use --, so unless the RAM copy of the code is modified, they tend to not use swap/paging file.
In most cases, some of the virtual memory range is reserved for the OS kernel. It does not mean that the kernel memory is visible to userspace, or accessible in any way; it is just a way to ensure that when transferring data to or from userspace processes, the OS kernel can use the userspace virtual memory addresses, and not mix them with its own internal addresses. Essentially, the OS kernel just won't create any virtual memory mappings to addresses it uses itself, for any userspace process, to make its own job simpler.
An interesting detail on Linux is that typically, the default stack size for new threads is rather large, 8 MiB (8,388,608 bytes) on 32-bit x86. Unless you set a smaller stack, the number of threads a process can create is limited by the available virtual memory. Each userspace process can use the lower 3 GiB, or virtual memory addresses below 3,221,225,472 on 32-bit x86; and you can fit at most 384 8 MiB stacks in that. If you account for the standard libraries and so on, typically on those systems a process can create about 300 threads, before it runs out virtual memory. If you use a much smaller stack, say 65536 bytes, a process can create thousands of threads even on 32-bit x86. Just remember that the issue there is running out of usable virtual memory address space, not memory per se.
add a comment |
Although David Schwartz already answered the stated questions, I'd like to talk about the underlying picture. So, do not consider this an answer, but an extended comment.
The problem is, the image shown is not a good representation of the address space a normal userspace application sees on current computers and operating systems.
Each process has their own address space. This is implemented using virtual memory; a mapping from virtual addresses to actual hardware accesses that is for all intents and purposes invisible to the userspace process. (Virtual memory is not per-address, but uses smallish chunks called pages. On all current architectures, each page is a power of two bytes in size. 212 = 4096 is common, but other sizes like 216 = 65536 and 221 = 2097152 are also used.)
Even when you use shared memory, it can reside at different virtual addresses for different processes. (This is also the reason you cannot really use pointers in shared memory.)
When a process is fork()ed, the virtual memory is cloned. (It is not really copied per se, as that would waste resources. Usually a technique called copy-on-write is used by the OS kernel, so that the actual same physical RAM is used for memory used by both/all processes, until one of them modifies their "copy"; at which point the OS kernel detaches the affected page duplicating its contents, before allowing the modifiaction to proceed.)
This means that after a fork(), the parent and child processes will have their stacks at exactly the same virtual addresses.
The only limit is how much actual RAM there is available. Actually, the OS kernel can also move currently unused files to swap or paging file; but if those pages end up being needed soon, it slows down the operation of the machine. On Linux at least, binaries and libraries also get directly mapped to their respective files -- that being the reason why you can't modify executable files when they are in use --, so unless the RAM copy of the code is modified, they tend to not use swap/paging file.
In most cases, some of the virtual memory range is reserved for the OS kernel. It does not mean that the kernel memory is visible to userspace, or accessible in any way; it is just a way to ensure that when transferring data to or from userspace processes, the OS kernel can use the userspace virtual memory addresses, and not mix them with its own internal addresses. Essentially, the OS kernel just won't create any virtual memory mappings to addresses it uses itself, for any userspace process, to make its own job simpler.
An interesting detail on Linux is that typically, the default stack size for new threads is rather large, 8 MiB (8,388,608 bytes) on 32-bit x86. Unless you set a smaller stack, the number of threads a process can create is limited by the available virtual memory. Each userspace process can use the lower 3 GiB, or virtual memory addresses below 3,221,225,472 on 32-bit x86; and you can fit at most 384 8 MiB stacks in that. If you account for the standard libraries and so on, typically on those systems a process can create about 300 threads, before it runs out virtual memory. If you use a much smaller stack, say 65536 bytes, a process can create thousands of threads even on 32-bit x86. Just remember that the issue there is running out of usable virtual memory address space, not memory per se.
Although David Schwartz already answered the stated questions, I'd like to talk about the underlying picture. So, do not consider this an answer, but an extended comment.
The problem is, the image shown is not a good representation of the address space a normal userspace application sees on current computers and operating systems.
Each process has their own address space. This is implemented using virtual memory; a mapping from virtual addresses to actual hardware accesses that is for all intents and purposes invisible to the userspace process. (Virtual memory is not per-address, but uses smallish chunks called pages. On all current architectures, each page is a power of two bytes in size. 212 = 4096 is common, but other sizes like 216 = 65536 and 221 = 2097152 are also used.)
Even when you use shared memory, it can reside at different virtual addresses for different processes. (This is also the reason you cannot really use pointers in shared memory.)
When a process is fork()ed, the virtual memory is cloned. (It is not really copied per se, as that would waste resources. Usually a technique called copy-on-write is used by the OS kernel, so that the actual same physical RAM is used for memory used by both/all processes, until one of them modifies their "copy"; at which point the OS kernel detaches the affected page duplicating its contents, before allowing the modifiaction to proceed.)
This means that after a fork(), the parent and child processes will have their stacks at exactly the same virtual addresses.
The only limit is how much actual RAM there is available. Actually, the OS kernel can also move currently unused files to swap or paging file; but if those pages end up being needed soon, it slows down the operation of the machine. On Linux at least, binaries and libraries also get directly mapped to their respective files -- that being the reason why you can't modify executable files when they are in use --, so unless the RAM copy of the code is modified, they tend to not use swap/paging file.
In most cases, some of the virtual memory range is reserved for the OS kernel. It does not mean that the kernel memory is visible to userspace, or accessible in any way; it is just a way to ensure that when transferring data to or from userspace processes, the OS kernel can use the userspace virtual memory addresses, and not mix them with its own internal addresses. Essentially, the OS kernel just won't create any virtual memory mappings to addresses it uses itself, for any userspace process, to make its own job simpler.
An interesting detail on Linux is that typically, the default stack size for new threads is rather large, 8 MiB (8,388,608 bytes) on 32-bit x86. Unless you set a smaller stack, the number of threads a process can create is limited by the available virtual memory. Each userspace process can use the lower 3 GiB, or virtual memory addresses below 3,221,225,472 on 32-bit x86; and you can fit at most 384 8 MiB stacks in that. If you account for the standard libraries and so on, typically on those systems a process can create about 300 threads, before it runs out virtual memory. If you use a much smaller stack, say 65536 bytes, a process can create thousands of threads even on 32-bit x86. Just remember that the issue there is running out of usable virtual memory address space, not memory per se.
answered Nov 14 '18 at 2:07
Nominal AnimalNominal Animal
30k33361
30k33361
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53291801%2fchild-processes-memory-allocation-and-the-purpose-of-reaping-child-processes%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
For Q1: Consider a parent process forking a child process. When the child process terminates, the OS continues to store information about the return status of the child process so that when the parent calls waitpid it can get the return status. Only after the parent calls waitpid, can the OS can reap the child process.
– MFisherKDX
Nov 14 '18 at 1:21
@MFisherKDX so is the purpose of reaping child processes is just to get return statuses of child processes?
– amjad
Nov 14 '18 at 1:27
Have a read here: Zombie Process
– MFisherKDX
Nov 14 '18 at 1:33