从前端到后端,龙哥讲nodejs基础(七)

服务器


当我们从一个前端或者后端走向全栈的时候,都会遇到一个问题:我人生中的第一台云主机(服务器)应该买什么配置的。

是不是cpu核心越多,内存越大,硬盘容量越高越好??

相信大多数同学都有这个疑惑,一定是越贵的主机,性能就越好吗?理论上来说,是这样的,但是这并不代表你就应该多花那些冤枉钱—因为nodejs是单线程的,你想一个进程,一个线程的程序(就算它到了i/o环节最多也就是4个一组去执行)它对资源的消耗是很小的。如果你的项目比较简单,简单到根本不需要调用第二个进程去干这件事儿,那么单核cpu就够了。

我什么时候需要多线程


当你的项目非常庞大的时候,庞大到什么程度,举个例子,比如用户登录和用户在系统中修改某个数据。

这两个操作,没有任何直接关联,甚至他们发生的时间段都不同,比如用户,10点登录了,12点修改了某个数据。此时,这两个操作没有直接关系,但是,这两个操作都需要消耗很多的系统资源—比如几十万个用户在频繁的登录..此时,就有必要给这两个任务区分进程去执行了!

分开两个进程可以有效的增加系统资源利用率。后面我们会讲这是为什么。
这里你只需要了解,一个cpu,一次只能处理一个进程,但是如果有两个cpu,他可以同时处理两个进程,分进程就好处就体现出来了。那么,什么是线程,什么是进程呢?

什么是线程,什么是进程


说实话,看到这个东西,绝大多数人是懵逼的,就连我认识的一些从业几年的同事,一时半会也解释不清。

今天龙哥将会用最简单的几句话为你讲明白:首先,在讲这两个东西之前,我们要了解电脑是怎么运作的...

杠精马上反问:线程跟进程,你扯什么计算机原理啊?

别急,因为线程和进程就是基于这个来的。

我们都知道,组成一台计算机(这里指主机,不包括显示器,键盘等外设)。最核心的就是这几个东西,cpu,内存,硬盘,主板。

那么,你知道它的工作流程是什么样的吗?其实你会发现,这里面除了cpu是用来计算数据的,其他的东西都只干一件事,那就是储存。

无论是哪个硬件发送来一条指令,这些指令都会形成一个队列,然后一个接一个发送都cpu那里去处理,放心,cpu的执行效率高的惊人,惊人到一个一个处理,会让人误以为是并行完成的。

而这个调用cpu转一圈出来的流程,人们称之为:流。

然后你该说了, 这跟进程和线程有什么关系??

所谓的进程,就是一个运行中的程序,比如,我们开了一个QQ,打开任务管理器,你看到这个QQ就是一个进程。

注意,这里就很关键了,我们前面说,cpu一次只能处理一个指令,而这个指令就是进程。

然后,当这个进程不活动的时候,它的数据就被储存在内存中,内存也叫这个程序的暂存器。

好,先别蒙,那我们简单来说,一个程序就是一个进程。那nodejs就似乎一个进程了呗?对,完全正确,我们运行的环境,包括mysql,redis这些程序都是独自占一个进程。

行,那么线程呢,老有人说,多线程,多线程有什么用??

单线程和多线程


首先我得告诉你,nodejs是单线程的。所谓线程,就是在一个程序(进程)中,任务是怎么处理的。

如果是多线程,就是多个任务一起执行,单线程,就是一个一个执行。

但是,前面我们说了。最后处理这个任务的,并不是内存,而是cpu啊。cpu一次只能执行一个任务。所以多个进程,多个线程,只是看上去是并行的,其实最后还是一个一个执行。

所以,多个核cpu就是为了解决这个问题而存在的。。理论上来说,你的硬件越牛逼,cpu核数越多,你调用多线程或者多进程的收益也就越大。但是,花的钱也就越多。。

区别


那照你这么说,他俩就没什么区别了呗。有区别,进程里面是包含线程的,所以,当你需要多个cpu同时处理的时候,需要建立多个进程,当需要一个进程里面的任务,分别运行的时候,需要多个进程。

好我讲完了。那么你发现问题了吗?

nodejs是单线程的,我说了两遍了。如果是这样,那么它岂不是在cpu使用上,不如java等可以多进程的语言了吗??

nodejs


还真不是,nodejs只是看上去是单线程的。因为js是浏览器语言所以它必须是单线程。但是,真到了执行的步骤,你可管不了它怎么运作。

引用博客园牛人的解释:

node.js采用单线程异步非阻塞模式,也就是说每一个计算独占cpu,遇到I/O请求不阻塞后面的计算,当I/O完成后,以事件的方式通知,继续执行计算2。

但nodejs真的是单线程吗?其实只有js执行是单线程,I/O显然是其它线程。js执行线程是单线程,把需要做的I/O交给libuv,自己马上返回做别的事情,然后libuv在指定的时刻回调就行了。其实简化的流程就是酱紫的!细化一点,nodejs会先从js代码通过node-bindings调用到C/C++代码,然后通过C/C++代码封装一个叫 “请求对象” 的东西交给libuv,这个请求对象里面无非就是需要执行的功能+回调之类的东西,给libuv执行以及执行完实现回调。

你可以发现,其实nodejs在执行的时候,并不是一个挨着一个去执行,而是,以一个队列的形式,封装一个任务就回来继续回来往下走,而那个封装的任务是交给底层的线程池去完成的。这是最骚的。

其次,nodejs可以开启子进程,虽然也是多线程,但是它提供了一个主从关系。(你只需要理解nodejs也可以才用多线程模式运行就行了)所以,nodejs用来处理高并发是完全不在话下的。

好了,最后上几个例子大家体验一下吧。

同步进程:

var fs=require("fs");
function foo(){
   function beginAnotherTask(){
       var file=fs.createReadStream("./yishengyouni.mp3");
       file.on("data",function(data){
          console.log("读取到%d字节。",data.length)
       });
      process.nextTick(beginAnotherTask);
   }
}
var file=fs.createReadStream("./yishengyouni.mp3");
file.on("data",function(data){
   console.log("读取到%d字节。",data.length)
});
foo();

使用next.Tick方法可以讲一个任务,推迟到下一个异步或者同步方法的执行时。

多进程
使用child_process的spawn方法开启多个进程
并通过spawn中的stdio属性来关联两个进程(管道)

var cp=require("child_process");
var sp1=cp.spawn("node",["test1.js","one","tow","three","four"],{cwd:"./test"});
var sp2=cp.spawn("node",["test2.js"],{stdio:"pipe"});
sp1.stdout.on("data",function(data){
   console.log("子进程标准输出:"+data);
   sp2.stdin.write(data);
});
sp1.on("exit",function(code,signal){
   console.log("子进程退出:"+code);
   process.exit();
});
sp1.on("error",function(err){
   console.log("子进程开启失败:"+err);
   process.exit();
})
process.stdout.write("子进程当前工作目录为:"+process.cwd());
process.argv.forEach(function(val,index,array){
   process.stdout.write("\r\n"+index+":"+val);
})
var fs=require("fs");
var out=fs.createWriteStream("./message.txt");
process.stdin.on("data",function(data){
   out.write(data);
})
process.stdin.on("end",function(data){
   process.exit();
})

注意:目录的结构

test2是在test文件夹外面的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容