Skip to content

Commit 0b660e6

Browse files
committed
Finished fork overview
1 parent 3d17a2a commit 0b660e6

1 file changed

Lines changed: 62 additions & 49 deletions

File tree

child-processes/index.md

Lines changed: 62 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,16 @@ author: ian
77

88
_Prerequisites: [events](../events), [streams](../buffers-and-streams)_
99

10+
The typical operating system has different processes running in the background, and each process is being managed by a single-core of our CPU and will run a series of calculations each time it is being ticked. To take full advantage of our CPU using a single process, we would need a number of processes that is at least equal to the number of cores in our CPU. In addition, each process might be responsible for running a series of calculations of different logic, which will give the end user a better control over the CPU’s behavior.
11+
1012
The `child_process` module provides the ability to spawn child processes and interact with other programs. Whilst single-threaded, non-blocking performance in Node.js is great for a single process, we can use `child_process` to handle the increasing workload in our applications in multiple threads.
1113

1214
Using multiple processes allows a Node application to scale. Node is designed for building distributed applications with many nodes, hence it's name Node.
1315

1416
Pipes for `stdin`, `stdout`, and `stderr` are established between the parent Node process and the spawned subprocess. The behaviour matches that of pipes in the shell.
1517

18+
The examples in this article are all Linux-based. On Windows, you will need to switch the commands I use with their Windows alternatives or use a Linux-like shell.
19+
1620
# `exec` vs `spawn`
1721

1822
There are two main approaches to running child processesL `exec` and `spawn`.
@@ -23,8 +27,7 @@ There are two main approaches to running child processesL `exec` and `spawn`.
2327
| buffers the data (waits until the process finishes and transfers all the data ) | Streams the data returned by the child process (data flow is constant) |
2428
| maximum data transfer 200kb (by default | has no data transfer size limit |
2529

26-
Typically, `spawn` is more suitable for long-running process with large outputs. spawn streams input/output with child process. `exec` buffered output in a small (by default 200K) buffer.
27-
30+
Typically, `spawn` is more suitable for long-running process with large outputs. spawn streams input/output with child process. `exec` buffered output in a small (by default 200K) buffer.
2831

2932
## A Simple `exec`
3033

@@ -103,26 +106,65 @@ wc.on('close', (code) => {
103106
```
104107
</div>
105108

106-
107109
# fork
108110

111+
`fork` is a special version of `spawn' that allows messages to be sent between the Node processes.
112+
113+
Unfortunately, we are unable to run this example in the REPL because it requires separate files. So this example is best run locally on your favourite terminal.
114+
115+
In this example, we are going to create a child process that can receive a number, and then calculates the fibonacci of that number. This has been implemented inefficiently to illustrate long running processes. The `message` event is used to listen for requests, and the payload is destructed for a numerical value, `n`.
116+
117+
```javascript
118+
119+
const fibonacci = (num) => num <= 1 ? 1 : fibonacci(num - 1) + fibonacci(num - 2)
120+
121+
process.on('message', ({ n }) => {
122+
process.send({ fib: fibonacci(n), n })
123+
// optional - there is no reason why this child process
124+
// can't be called multiple times.
125+
process.exit()
126+
})
127+
128+
```
129+
130+
The parent process creates 3 child processes, and passes a range of numbers to them for calculating.
109131

110-
_To do_
132+
```javascript
111133

112-
child_process.fork(): spawns a new Node.js process and invokes a specified module with an IPC communication channel established that allows sending messages between parent and child.
134+
const { fork } = require('child_process')
113135

136+
const child1 = fork('fork-child')
137+
const child2 = fork('fork-child')
138+
const child3 = fork('fork-child')
114139

140+
// send data to the child process to perform the calculation
141+
child1.send({ n: 5 });
142+
child2.send({ n: 10 });
143+
child3.send({ n: 45 });
115144

116-
const exec_options = {
117-
cwd: null,
118-
env: null,
119-
encoding: 'utf8',
120-
timeout: 0,
121-
maxBuffer: 200 * 1024,
122-
killSignal: 'SIGTERM'
123-
};
145+
child1.on('message', (m) => {
146+
console.log('PARENT child1 got message:', m);
147+
});
148+
child2.on('message', (m) => {
149+
console.log('PARENT child2 got message:', m);
150+
});
151+
child3.on('message', (m) => {
152+
console.log('PARENT child3 got message:', m);
153+
});
124154

155+
child1.on('exit', () => {
156+
console.log('child1 exited');
157+
});
158+
child2.on('exit', () => {
159+
console.log('child2 exited');
160+
});
161+
child3.on('exit', () => {
162+
console.log('child3 exited');
163+
});
164+
```
165+
</div>
125166

167+
```
126168
127169
## ChildProcess Events
128170
@@ -136,45 +178,16 @@ The `child` processes communicates by emitting events to let the `parent` know w
136178
| `close` | The `stdio` streams of a child process get closed. |
137179
| `message` | This `child` process uses the `send` method to communicate with the parent. |
138180
181+
## A note on options
139182
140-
_Not reviwewed/edited after this_
141-
183+
These processes all accept an optional options object that allow us to control the context that the processes are run within. These vary for each method, and are described in detail in the [node documentation for `child_process`](https://nodejs.org/api/child_process.html).
142184
185+
## Summary
143186
187+
Parents `spawm`, `fork` or `exec` child processes, and communicate via events or pipes.
144188
189+
Take me to [cheat sheet]({{ "/cheatsheet/#child-process" | url }})
145190
146-
`spawn`
147-
148-
The first parameter is the path for an executable file that starts the process, and the second argument is the arguments that will be passed into the process.
149-
150-
151-
152-
153-
There are four different ways to create a child process in Node: spawn(), fork(), exec(), and execFile().
154-
155-
Note that examples I’ll be using in this article are all Linux-based. On Windows, you need to switch the commands I use with their Windows alternatives. - find what they are...
156-
157-
158-
spawn - spwans a new process, which can pass the command any arguments
159-
160-
161-
162-
163-
So we can interact with the `ChildProcess` by listening for a series of events.
164-
165-
166-
```
167-
168-
169-
As you probably know, our typical OS has different processes running in the background. Each process is being managed by a single-core of our CPU and will run a series of calculations each time it is being ticked. As such, we can’t take full advantage of our CPU using a single process, we would need a number of processes that is at least equal to the number of cores in our CPU. In addition, each process might be responsible for running a series of calculations of different logic, which will give the end user a better control over the CPU’s behavior.
170-
171-
Why is this module called child_process and not just process? First of all, not to confuse with the main process instance global.process, and second, the child process is derived from the main process, which means that both can communicate - the main process will hold streams for the child process’s std types and they will both share an ipc channel (“Inter Process Communication” channel; more on that further this article).
172-
173-
174-
175-
176-
177-
```
191+
## Exercise
178192
179-
More reading: [Node.js Child Processes: Everything you need to know
180-
](https://www.freecodecamp.org/news/node-js-child-processes-everything-you-need-to-know-e69498fe970a/)
193+
Create a child process for doing some manipulation of a file or URL, and build a parent process that controls a number of these processes in parallel.

0 commit comments

Comments
 (0)