验证node单线程

现象

我们由一段代码入手(文件名:02.js);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const http = require("http");
let count = 0;
const server = http.createServer((req,res) => {
res.writeHead(200,{"Content-Type":"text/html;charset=UTF-8"});
res.write(`你是第${count++}个访问用户`);
res.end();
});
server.listen(3000,(err) => {
//出现错误的情况就是端口被占用
if(err) throw err;
console.log("server is running at http://localhost:3000/")
});

然后我们执行它

1
2
$ node 02.js
server is running at http://localhost:3000/

打开浏览器

单线程1

我们能看到“你是第0个访问用户”,当我们刷新的时候,我们发现…

  • 问题1:count并没有重新归零
  • 问题2:count直接由0变到了2

我们来看下问题1,count并没有重新归零,说明我们在刷新页面的时候并不是重新执行了整个脚本,而是只执行了server里的代码

1
2
3
4
5
const server = http.createServer((req,res) => {
res.writeHead(200,{"Content-Type":"text/html;charset=UTF-8"});
res.write(`你是第${count++}个访问用户`);
res.end();
});

所以count不会重新归零,而是执行里面的count++,但是…应该由0变为1啊。

好了,我们来看第二个问题,为什么直接从0变为2,我们打开调试工具

我们发现,刷新页面的时候会发送两个请求,一个是localhost,一个是favicon.ico,所以

1
res.write(`你是第${count++}个访问用户`);

会执行两次,然后我们就会看见0,2,4,6…

解决办法

做一个判断 if(req.url === "/favicon.ico") return;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const http = require("http");
let count = 0;
const server = http.createServer((req,res) => {
if(req.url === "/favicon.ico") return; //如果请求的是favicon.ico我们就return掉
res.writeHead(200,{"Content-Type":"text/html;charset=UTF-8"});
res.write(`你是第${count++}个访问用户`);
res.end();
});
server.listen(3000,(err) => {
//出现错误的情况就是端口被占用
if(err) throw err;
console.log("server is running at http://localhost:3000/")
});

单线程

我们再把代码修改一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const http = require("http");
let count = 0;
const server = http.createServer((req,res) => {
if(req.url === "/favicon.ico") return;
res.writeHead(200,{"Content-Type":"text/html;charset=UTF-8"});
res.write(`你是第${count++}个访问用户`);
+ //如果count计数到5的话,我们就让它阻塞
+ if(count === 5){
+ while(true) { }
+ }
res.end();
});
server.listen(3000,(err) => {
//出现错误的情况就是端口被占用
if(err) throw err;
console.log("server is running at http://localhost:3000/")
});

我们再来执行它,然后刷新刷新,count计数到5的时候就会阻塞,我们看

blocking

这是,我们重新开一个页面,输入http://localhost:3000

blocking

我们发现新开的页面也是阻塞的,为什么呢?就是因为node是单线程,一个地方阻塞了,就都阻塞了。


本文结束,感谢阅读。

本文作者:melody0z
本文链接:https://melodyvoid.github.io/Node/verify-node-single-thread.html
欢迎转载,转载请注明文本链接

坚持原创技术分享,您的支持将鼓励我继续创作!