异步式I/O与实践式编程
阻塞
线程在执行中如果遇到磁盘读写或网络通信(统称为I/O操作)通常要消耗很长时间 这时操作系统会剥夺这个线程的CPU控制权,使其暂停执行,同时将资源让给其他工作线程 异步I/O 非阻塞IO
针对所有的IO操作不采用阻塞的策略,当线程遇到IO操作时,不会以阻塞的方式等待IO操作完成或数据的返回,而只是将IO请求发送给操作系统,继续执行下一条语句。当操作系统完成IO操作时,以事件的形式通知执行IO操作的线程,线程会在特定时候处理这个事件。
为了处理异步IO 线程必须有事件循环 不断地检查有咩有未处理的事件 依次处理 单线程事件驱动的异步式I/O比较传统的多线程阻塞式I/O优势?
异步式I/O就是少了多线程的开销 对于操作系统来说,创建线程的代价十分昂贵
需要分配内存 列入调度 同时在线程切换时还要执行内存换页 CPU的缓存被清空
切换回来还要从中心从内存中读信息 破坏了数据的局部性 同步式I/O(阻塞式) 异步I/O(非阻塞式)
利用多线程提供吞吐量 单线程即可实现高吞吐量
通过事件片段分割和线程调度利用多核CPU 通过功能的划分利用多核CPU
需要由操作系统调度多线程受用多核CPU 可以将单进程绑定到单核CPU
难以充分利用CPU资源 可以充分利用CPU资源
内存轨迹大 数据局部性弱 内存轨迹小 数据局部性强
符合线性的编程思维 不符合传统编程思维 fs.readFile("fileName", "编码",回调函数) //fileName不能是中文
var data = fs.readFileSync("fileName", "编码")
以上两种分别为异步读文件 和 同步读文件 Node.js的事件循环机制(有疑问 具体流程还是不了解)
Node.js在什么时候会进入事件循环呢?
Node.js程序由事件循环开始,到事件循环结束,所有的逻辑都是事件的回调函数,所以Node.js一直处在事件循环中,程序入口就是事件循环第一个事件的回调函数。事件的回调函数在执行的过程中,可能会发出I/O请求或直接发射(emit)事件,执行完毕后再返回事件循环,事件循环会检查事件队列中未处理的事件,直到程序结束 模块
创建模块
一个文件就是一个模块 问题点如何在其他文件中获取这个模块
node exports 和 require两个对象
exports 模块公开的接口
require 用于从外部获取一个模块的接口 即所获取模块的exports对象 require加载模块 只加载一次 都是同一个实例 类似于 单例模式 警告:
不可以通过对exports直接赋值代替对module.exports赋值
exports实际上只是一个和module.exports指向同一个对象的变量
exports本身会在模块执行结束后释放
但是module不会,因此只能通过指定的module.exports来访问接口
exports = Hello; 报错 Hello 不是一个函数
写成 modules.exports = Hello;-->var Hello = require("./Hello")
exports.hello = Hello; ---> var Hello = require("./Hello").Hello; 创建包
创建包 需要符合CommonJS规范 CommonJS规范如下
package.json 必须在包的顶层目录下;
二进制文件应该在 bin 目录下;
JavaScript 代码应该在 lib 目录下;
文档应该在 doc 目录下;
单元测试应该在 test 目录下。 node getpackage.js 控制台打印出Hello Node.js在调用某个包时,会首先检查包中package.json文件的main字段,将其作为包的接口模块
未配置package.json 时 会尝试寻找index.js或index.node为入口文件 我们使用这种方法可以把文件夹封装为一个模块,即所谓的包。包通常是一些模块的集合,在模块的基础上提供了更高层的抽象,
相当于提供了一些固定接口的函数库 通过定制package.json 我们可以创建更复杂的 规范 完善的包用语发布 package.json是用来描述CommonJS规范的,完全符合package.json文件应该含有一下字段
name 包的名称 必须是唯一的 由小写英文字母 数字 下划线组成 不能包含空格
description 包的简要说明
version 符合语义化版本识别规范的版本字符串
keywords 关键字数组 通常用于搜索
maintainers 维护者数组 每个元素包含 name email(可选) web(可选)
contributors 贡献者数组 格式同上 包的作者应该是贡献者数组的第一个元素
bugs 提交bug的地址 可以是网址或者电邮
licenses 许可证数组 每个元素要包含type(许可证的名称)和url(链接到许可证文本的地址)字段
repositories 仓库托管地址数组 每个元素要包含type(仓库的类型 如git) url(仓库地址) path(相对于仓库的路径 可选) 字段
dependencies 包的依赖 一个关联数组 由包的名称和版本号组成 example
{
"name": "mypackage",
"description": "Sample package for CommonJS. This package demonstrates the required
elements of a CommonJS package.",
"version": "0.7.0",
"keywords": [
"package",
"example"
],
"maintainers": [
{
"name": "Bill Smith",
"email": "bills@example.com",
}
],
"contributors": [
{
"name": "BYVoid",
"web": "http://www.byvoid.com/"
}
],
"bugs": {
"mail": "dev@example.com",
"web": "http://www.example.com/bugs"
},
"licenses": [
{
"type": "GPLv2",
"url": "http://www.example.org/licenses/gpl.html"
}
],
"repositories": [
{
"type": "git",
"url": "http://github.com/BYVoid/mypackage.git"
}
],
"dependencies": {
"webkit": "1.2",
"ssl": {
"gnutls": ["1.0", "2.0"],
"openssl": "0.9.8"
}
}
} Node.js的require在加载模块时会尝试搜索 node_modules 子目录 因此使用npm本地安装的包可以直接引用 使用npm全局安装的包(example supervisor) 主要是为了在环境变量中注册supervisor 可以在命令行中使用
npm本地安装仅仅 把包安装到node_modules子目录下 其中的bin目录没有包含在PATH环境变量中 不能直接在命令中调用
使用全局模式安装 npm会将包安装到系统目录 譬如 /usr/local/lib/node_modules 同时package.json文件中的bin字段包含的文件会被链接到/usr/local/bin /usr/local/bin是在PATH环境变量中默认定义的 因此可以直接在命令行中使用 提示:使用全局安装的包并不能直接在js文件中用require获得 因为require不会搜索/usr/local/node_modules/ npm link npm link express 可以在node_modules子目录中发现一个指向安装全局包的符号链接 通过这种方法可以使全局包当本地宝使用(不支持window) npm link 可以将本地的包链接到全局
使用方法:在包目录(package.json所在目录)中运行npm link 命令 发布包
发布之前需要获得一个账号用于维护自己的包 使用npm adduser 根据提示输入用户名 密码 邮箱
npm whoami 检测帐号是否存在
在package.json所在目录使用npm publish 发布
npm unpublish取消发布
如果包有更新 package.json文件中修改version即可 ?????????????疑惑?????????????
1: exports本身会在模块执行结束后释放( 被释放exports.Hello = Hello怎么还会被访问到呢???? )
解答
Node不允许重写exports exports = Hello; 如果创建的返回 既有exports.hello 又有 module.exports = 则以module为准 上面的问题可以理解为 导出的究竟是什么
最终程序导出的事module.exports; exports只是对module.exports的一个全局引用 最初被定义为一个可以添加属性的空对象 所以exports.Hello 只是module.exports.Hello 的简写
如果把exports定义成别的 就打破了module.exports 和 exports之间的引用关系 感觉像是A关联B B关联A 最后倒出A 但是B指向了C 与A断开了联系 导出A的时候A找不到B 所以报错
2: 语义化版本识别
3: Node.js调试 还未接触
异步式I/O与实践式编程的更多相关文章
- NodeJS示例异步式(Asynchronous)IO与同步式Synchronous)IO
理解IO IO(Input/Output)通常是指计算机线程进行慈磁盘读写或者网络通信时的一种行为. 同步式(Synchronous)IO和异步式(Asynchronous )IO ...
- html响应式布局,css响应式布局,响应式布局入门
html响应式布局,css响应式布局,响应式布局入门 >>>>>>>>>>>>>>>>>>& ...
- CSS的三种样式:内联式,嵌入式,外部式以及他们的优先级
从CSS 样式代码插入的形式来看基本能够分为下面3种:内联式.嵌入式和外部式三种. 1:内联式css样式表就是把css代码直接写在现有的HTML标签中,如以下代码: <p style=" ...
- [Selenium]显式等待 Explicit wait & 隐式等待 Implicit wait
显式等待 Explicit wait 显示等待 , 就是明确的要等到某个元素出现或者某个元素满足某种条件,每隔一段时间检查一次,等不到,就一直等,如果在规定的时间内还没有找到,就跳出来检查间隔的时间和 ...
- python列表推导式详解 列表推导式详解 字典推导式 详解 集合推导式详解 嵌套列表推导式详解
推导式是Python中很强大的.很受欢迎的特性,具有语言简洁,简化代码,速度快等优点.推导式包括:1.列表推导式2.字典推导式3.集合推导式4.嵌套列表推导式注意: 字典和集合推导是最近才加入到Pyt ...
- RTX——第10章 任务调度-抢占式、时间片和合作式
以下内容转载自安富莱电子: http://forum.armfly.com/forum.php 本章教程为大家将介绍 RTX 操作系统支持的任务调度方式,抢占式,时间片和合作式,这部分算是RTX 操作 ...
- FreeRTOS——任务调度—抢占式,时间片和合作式
以下转载自安富莱电子: http://forum.armfly.com/forum.php 本章教程为大家将介绍 FreeRTOS 操作系统支持的任务调度方式:抢占式,时间片和合作式,这部分算是 Fr ...
- 20121124.Nodejs异步式I/O与事件式编程
异步: 你请人吃饭,准备一起去的.结果那人刚好有事,让你先去点菜,你去点好菜,他忙完就来了,这就是异步的优势(不耽误事!)同步: 就是,你必须等那个人忙完了,才一起去(浪费时间) 理解来源于群友&qu ...
- 通过实例让你真正明白mapreduce---填空式、分布(分割)编程
本文链接:http://www.aboutyun.com/thread-8303-1-1.html 问题导读: 1.如何在讲mapreduce函数中的字符串等信息,输出到eclipse控制台?2.除了 ...
随机推荐
- commons -lang(2) RandomStringUtils RandomUtils
上一篇是StringUtils 链接http://www.cnblogs.com/tele-share/p/8060129.html 1.RandomStringUtils 1.1模拟实现random ...
- windows 下进程池的操作
在Windows上创建进程是一件很容易的事,但是在管理上就不那么方便了,主要体现在下面几个方面: 1. 各个进程的地址空间是独立的,想要在进程间共享资源比较麻烦 2. 进程间可能相互依赖,在进程间需要 ...
- Java JSON数据处理
比方说要处理这么 {"data":[{"salt":"","plaintext":"xiaoxu", ...
- JQEUI问题收集
JQEUI问题收集大家在使用JQEUI的过程中如遇到任何问题或是建议均可在此留言,作者会尽快回复.JQEUI社区也在积极的开发中,敬请期待-- JQEUI官网:http://www.jqeui.com ...
- C#学习笔记-建造者模式
题目:用程序画一个小人. 实现: public partial class Form1 : Form { public Form1() { InitializeComponent(); } priva ...
- 关于soapui简介与入门
SoapUI简介 SoapUI是一个开源测试工具,通过soap/http来检查.调用.实现Web Service的功能/负载/符合性测试.该工具既可作为一个单独的测试软件使用,也可利用插件集成到Ecl ...
- Modelsim独立仿真Vivado Clocking Wizard IP Core
工欲善其事,必先利其器.在使用Vivado自带的仿真软件仿真的时候,相对于更优秀的仿真工具Modelsim,效率低了很多,为了更高效的开发,我尝试着用Vivado级联Modelsim仿真,但是级联后还 ...
- 表单中GET与POST的区别
1.本质 Get是向服务器发索取数据的一种请求,而Post是向服务器提交数据的一种请求. 2.服务器端获取值的方法 get方式提交的数据,服务器端使用request.QueryString获取变量的值 ...
- CTF---隐写术入门第三题 打不开的文件
打不开的文件分值:10 来源: 实验吧 难度:中 参与人数:2718人 Get Flag:1222人 答题人数:1276人 解题通过率:96% 咦!这个文件怎么打不开? 解题链接: http://ct ...
- POJ 1804 Brainman(5种解法,好题,【暴力】,【归并排序】,【线段树单点更新】,【树状数组】,【平衡树】)
Brainman Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 10575 Accepted: 5489 Descrip ...