Node.js API —— process(进程)

// 说明
    Node API 版本为 v0.10.31。
    中文参考:http://nodeapi.ucdok.com/#/api/http://blog.sina.com.cn/oleoneoy
    本段为博主注解。

目录

进程
    ○ Event: ‘exit‘
    ○ Event: ‘uncaughtException‘
    ○ Signal Events
    ○ process.stdout
    ○ process.stderr
    ○ process.stdin
    ○ process.argv
    ○ process.execPath
    ○ process.execArgv
    ○ process.abort()
    ○ process.chdir(directory)
    ○ process.cwd()
    ○ process.env
    ○ process.exit([code])
    ○ process.getgid()
    ○ process.setgid(id)
    ○ process.getuid()
    ○ process.setuid(id)
    ○ process.getgroups()
    ○ process.setgroups(groups)
    ○ process.initgroups(user, extra_group)
    ○ process.version
    ○ process.versions
    ○ process.config
    ○ process.kill(pid, [signal])
    ○ process.pid
    ○ process.title
    ○ process.arch
    ○ process.platform
    ○ process.memoryUsage()
    ○ process.nextTick(callback)
    ○ process.maxTickDepth
    ○ process.umask([mask])
    ○ process.uptime()
    ○ process.hrtime()

进程

    process 对象是一个全局对象,能在任何地方被访问。它是一个 EventEmitter 实例。

Event: ‘exit‘

    当进程将要退出时发射。在这个时候没有任何途径来阻止退出事件循环,且当所有的 exit 监听器运行完之后进程将会退出。因此,在本监听器内你必须只使用同步的操作。这是一个很好的执行模块状态的检验的钩子(比如用于单元测试上)。回调函数有一个参数,即进程的退出码。
    监听 exit 的例子:
1 process.on(‘exit‘, function(code) {
2   // do *NOT* do this
3   setTimeout(function() {
4     console.log(‘This will not run‘);
5   }, 0);
6   console.log(‘About to exit with code: ‘, code);
7 });

Event: ‘uncaughtException‘

    当一个异常一路冒泡到事件循环时发射。如果为这个异常添加了一个监听器,那么默认的动作(打印堆栈信息并退出)将不会被触发。
    监听 uncaughtException 的例子:
 1 process.on(‘uncaughtException‘, function(err) {
 2   console.log(‘Caught exception: ‘ + err);
 3 });
 4 
 5 setTimeout(function() {
 6   console.log(‘This will still run.‘);
 7 }, 500);
 8 
 9 // Intentionally cause an exception, but don‘t catch it
10 nonexitstentFunc();
11 console.log(‘This will not run.‘);

    注意 uncaughtException 是一种非常粗鲁的异常捕获途径且有可能在将来移除。
    不要使用它,使用 domains 取代。如果你使用了它,在每个没被正常捕获的异常后重启你的应用程序。
    不要使用它因为 node.js 相当于出了错待会恢复重新开始。一个未捕获的异常意味着你的应用程序——推而广之 node.js 本身处于未知状态。盲目地恢复意味着什么事情都有可发生。
    假想当你正在升级系统时拔了电源线,然后恢复了。十次有九次都没事发生——但在第十次,你的系统就崩了。
    你已经被警告过。

Signal Events

    当进程受到一个信号时发射。参看 sigaction(2) 列出的标注 POSIX 信号,例如 SIGINT,SIGHUP等。
    监听 SIGINT 的例子:
1 // Start reading from stdin so we don‘t exit.
2 process.stdin.resume();
3 
4 process.on(‘SIGINT‘, function() {
5   console.log(‘Got SIGINT. Press Control-D to exit.‘);
6 });

    在大多数的终端程序中一个简单的发送 SIGINT 信号的方法是使用 Control-C
    注意:

  • SIGUSR1 被 node.js 保留用以启动 debugger。可以创建一个监听器但那不会停止 debugger 的启动。
  • SIGTERM 和 SIGINT 在非 Windows 平台下有默认的监听器,退出并在退出前重置终端 mode 为128加信号数值。如果这两信号之一创建了监听器,它们的默认操作将会被移除(node 将永不退出)。
  • SIGPIPE 默认被忽略,他可以创建监听器。
  • SIGHUP 在 Windows 下当控制台窗口被关闭时产生,在其他平台各个类似的条件下,参看 signal(7)。它可以创建监听器,然而 node 将在大约10秒后被 Windows 无条件终止。在非 Windows 平台下,SIGHUP 的默认行为是终止 node,但一旦创建了监听器默认的行为将被移除。
  • SIGTERM 在 Windows 下不支持,可以被监听。
  • SIGINT 从终端发送该信号能被所有平台支持,且通常可以用 CTRL+C 产生(即使这是可配置的)。当终端 raw 模式启动时它不能被产生。
  • SIGBREAK 在 Windows 下当按下 CTRL+BREAK 时产生,在非 Windows 平台下可以别监听,但没有途径可以发送或产生它。
  • SIGWINCH 当控制台改变大小时产生。在 Windows 下,这只会发生在鼠标正在移动时向控制台输入,或刻度的 tty 在 raw 模式下使用。
  • SIGKILL 不可被监听,在任何平台下 node 都将无条件终止。
  • SIGSTOP 不可被监听。

    注意 Windows 不支持发送信号,但 node 使用 process.kill()child_process.kill() 提供了一些模拟:——发送信号0可以用来查找进程是否存在——发送 SIGINTSIGTERMSIGKILL 让目标进程无条件退出。

process.stdout

    写向标准输出可写流
    例子:console.log 的定义
1 console.log = function(d) {
2   process.stdout.write(d + ‘\n‘);
3 };

    process.stderrprocess.stdout 和 Node 中的其他流不同,向它们写入通常是阻塞的。

  • 当它们指向普通文件或 TTY 文件描述符时它们是阻塞的。
  • 当它们指向管道:
      ○ 在 Linux/Unix 下是阻塞的。
      ○ 在 Windows 下与其他流一样是非阻塞的。
    要检验 Node 是否运行在 TTY 上下文中,参看 process.stderrprocess.stdoutprocess.stdinisTTY 属性:
 
$ node -p "Boolean(process.stdin.isTTY)"
true
$ echo "foo" | node -p "Boolean(process.stdin.isTTY)"
false

$ node -p "Boolean(process.stdout.isTTY)"
true
$ node -p "Boolean(process.stdout.isTTY)" | cat
false

    更多信息参看 tty 文档

process.stderr

    写向标准错误输出的可写流。
    process.stderr 和 process.stdout 和 Node 中的其他流不同,向它们写入通常是阻塞的。
  • 当它们指向普通文件或 TTY 文件描述符时它们是阻塞的。
  • 当它们指向管道:
      ○ 在 Linux/Unix 下是阻塞的。
      ○ 在 Windows 下与其他流一样是非阻塞的。

process.stdin

   标准输入的可写流
    打开标准输入并监听两个事件的例子:
 1 process.stdin.setEncoding(‘utf8‘);
 2 
 3 process.stdin.on(‘readable‘, function() {
 4   var chunk = process.stdin.read();
 5   if (chunk !== null) {
 6     process.stdout.write(‘data ‘ + chunk);
 7   }
 8 });
 9 
10 process.stdin.on(‘end‘, function() {
11   process.stdout.write(‘end‘);
12 });

    作为一个流,process.stdin 也可以用于“老”模式,那是为了兼容使用 v0.10 之前的 node 所写的代码。更多信息参看流兼容性
    在“老”模式下标准输入流默认是暂停的,所以必须调用 process.stdin.resume() 来从从里面读取。而且需要注意调用 process.stdin.resume() 本身会将流选择为“老”模式。
    如果你正在启动一个新项目,你应该选择更现代的“新”流模式而不是“老”的。

process.argv

    一个包含命令行参数的数组。第一个元素为 ‘node‘,第二个元素为 JavaScript 文件名。剩下的参数为附加的命令行参数。
1 // print process.argv
2 process.argv.forEach(function(val, index, array) {
3   console.log(index + ‘: ‘ + val);
4 });

    输出将会是:

$ node process-2.js one two=three four
0: node
1: /User/mjr/work/node/process-2.js
2: one
3: two=three
4: four

process.execPath

    这是启动进程的可执行程序的绝对路径。
     例子:
/usr/local/bin/node

process.execArgv

    这是启动进程的可执行程序的 node 特殊的命令行参数集。这些选项不会在 process.argv 出现,且不会包括 node 可执行程序,脚本名,或任何在脚本名后的选项。当为了使用父进程同样的执行环境创建子进程,这些参数是有用的。
    例子:
$ node --harmony script.js --version

    process.execArgv 的结果:

[--harmony]

   process.argv 的结果:

[/usr/local/bin/node, script.js, --version]

process.abort()

    这会导致 node 发射一个 abort。这回引起 node 退出并创建一个核心文件。

process.chdir(directory)

    改变进程的当前工作目录或如果失败则抛出一个异常。
1 console.log(‘Starting directory: ‘ + process.cwd());
2 try {
3   process.chdir(‘/tmp‘);
4   console.log(‘New directory: ‘ + process.cwd());
5 }
6 catch (err) {
7   console.log(‘chdir: ‘ + err);
8 }

process.cwd()

   返回进程的当前工作目录。
1 console.log(‘Current directory: ‘ + process.cwd());

process.env

    一个包含用户环境的对象。参看 environ(7)。 

process.exit([code])

    使用指定的 code 停止进程。如果省略,使用“成功”码 0 退出。
    使用一个“失败”码退出:
1 process.exit(1);

    执行 node 的 shell 将看到1作为退出码。

process.getgid()

    注意:这个函数只在 POSIX 平台下可用(也就是 Windows 不能使用)
    获取进程的组标识。(参看 getgid(2)。)这是数字组 id,不是组名。
1 if (process.gid) {
2   console.log(‘Current gid: ‘ + process.getgid());
3 }

process.setgid(id)

    注意:这个函数只在 POSIX 平台下可用(也就是 Windows 不能使用)
    设置进程的组标识。(参看 setgid(2)。)接收一个数值 ID 或一个组名字符串。如果组名指定,本函数阻塞直到将它解析为一个数值 ID。
 1 if (process.getgid && process.setgid) {
 2   console.log(‘Current gid: ‘ + process.getgid());
 3   try {
 4     process.setgid(501);
 5     console.log(‘New gid: ‘ + process.getgid());
 6   }
 7   catch (err) {
 8     console.log(‘Failed to set gid: ‘ + err);
 9   }
10 }

process.getuid()

    注意:这个函数只在 POSIX 平台下可用(也就是 Windows 不能使用)
    获取进程的用户标识。(参看 getuid(2)。)这是一个数值用户 id,不是用户名。
1 if (process.getuid) {
2   console.log(‘Current uid: ‘ + process.getuid());
3 }

process.setuid(id)

    注意:这个函数只在 POSIX 平台下可用(也就是 Windows 不能使用)
    设置进程的用户标识。(参看 setuid(2)。)接收一个数值 ID 或一个用户名字符串。如果用户名指定,本函数阻塞直到将它解析为一个数值 ID。
 1 if (process.getuid && porcess.setuid) {
 2   console.log(‘Current uid: ‘ + process.getuid());
 3   try {
 4     process.setuid(501);
 5     console.log(‘New uid: ‘ + process.getuid());
 6   }
 7   catch (err) {
 8     console.log(‘Failed to set uid: ‘ + err);
 9   }
10 }

process.getgroups()

    注意:这个函数只在 POSIX 平台下可用(也就是 Windows 不能使用)
    返回一个保存补充组 ID 的数组。如果有效组 ID 被包含在内 POSIX 不管它让它未指定,但 node.js 确保它总是。
// 说明:不熟悉 POSIX,真心看不懂。

process.setgroups(groups)

    注意:这个函数只在 POSIX 平台下可用(也就是 Windows 不能使用)
    设置补充组 ID。这是一个特权选项,意味着你需要为 root 用户或拥有 CAP_SETGID 的能力。
    列表可以包含组 ID,组名,或二者都包含。

process.initgroups(user, extra_group)

    注意:这个函数只在 POSIX 平台下可用(也就是 Windows 不能使用)
    使用用户名所在的所有组,读取/etc/group且初始化组可访问列表。这是一个特权选项,意味着你需要为 root 用户或拥有 CAP_SETGID 的能力。
    user 是一个用户名或用户 ID。extra_group 是一个组名或组 ID。
    当注销权限时需要注意。例子:
1 console.log(process.getgroups());         // [ 0 ]
2 process.initgroups(‘bnoordhuis‘, 1000);   // switch user
3 console.log(process.getgroups());         // [ 27, 30, 46, 1000, 0 ]
4 process.setgid(1000);                     // drop root gid
5 console.log(process.getgroups());         // [ 27, 30, 40, 1000 ]
// 说明:不熟悉 POSIX,真心看不懂。

process.version

    一个表示 NODE_VERSION 的编译进来的属性。
1 console.log(‘Version: ‘ + process.version);

process.versions

   一个表示 node 和它的依赖的版本字符串属性。
1 console.log(process.versions);

    将打印如下输出:

{ http_parser: 1.0,
  node: 0.10.4,
  v8: 3.14.5.8,
  ares: 1.9.0-DEV,
  uv: 0.10.3,
  zlib: 1.2.3,
  modules: 11,
  openssl: 1.0.1e }

process.config

    一个包含我们用来编译当前 node 可执行文件的配置选项的 JavaScript representation 的对象(//注:这里看不懂啥是 representation ,看英文吧)。这和运行 ./configure 脚本生成的“config.gypi"是一样的。
    可能的输出例子如下:
{ target_defaults:
  { cflags: [],
    default_configuration: ‘Release‘,
    defines: [],
    include_dirs: [],
    libraries: [] },
  variables:
  { host_arch: ‘x64‘,
    node_install_npm: ‘true‘,
    node_prefix: ‘‘,
    node_shared_cares: ‘false‘,
    node_shared_http_parser: ‘false‘,
    node_shared_libuv: ‘false‘,
    node_shared_v8: ‘false‘,
    node_shared_zlib: ‘false‘,
    node_use_dtrace: ‘false‘,
    node_use_openssl: ‘true‘,
    node_shared_openssl: ‘false‘,
    strict_aliasing: ‘true‘,
    target_arch: ‘x64‘,
    v8_use_snapshot: ‘true‘ } }

process.kill(pid, [signal])

    发送一个信号给进程 pidpid 为进程 id,signal 为描述发送的信号的字符串。信号名为形如 ‘SIGINT 或 ‘SIGHUP‘ 的字符串。如果省略,信号默认为 ‘SIGTERM‘。更多信息参看 Signal Events 和 kill(2)。
    如果目标进程不存在将抛出一个异常,且作为特例,信号 0 可以用来测试进程是否存在。
    注意只是因为这个函数的名字是 process.kill,它实际上只是一个信号发送者,如同系统调用 kill。信号发送后可以做其它事情而不仅仅杀死目标进程。
    发送信号给自己的例子:
 1 process.on(‘SIGHUP‘, function() {
 2   console.log(‘Got SIGHUP signal.‘);
 3 });
 4 
 5 setTimeout(function() {
 6   console.log(‘Existing.‘);
 7   process.exit(0);
 8 }, 100);
 9 
10 process.kill(process.pid, ‘SIGHUP‘);

    注意:当 Node.js 接收到 SIGUSR1 它会启动调试器,参看 Signal Events

process.pid 

    进程的 PID。
1 console.log(‘This process is pid ‘ + process.pid);

process.title

    用来设置在 ’ps‘ 中的显示什么的 getter/setter。
    当作为 getter 使用时,最大长度由系统指定,有可能是很短的。
    在 Linux 和 OS X 下,它受限于名字二进制大小加上命令行参数长度,因为它覆盖了参数内存。
    v0.8 通过也覆盖环境内存允许更长的进程标题字符串,但那有潜在的不安全性/在某些情况下会混乱(不仅是模糊不清)。

process.arch

    你运行在什么处理器架构上:‘arm‘‘ia32‘,或 ‘x64‘
1 console.log(‘This processor architecture is ‘ + process.arch);

process.platform

    你运行在什么平台上:‘darwin‘‘freebsd‘‘linux‘‘sunos‘,或 ‘win32‘
1 console.log(‘This platform is ‘ + process.platform);

process.memoryUsage()

    返回一个描述 Node 进程内存使用的对象,单位是字节。
1 var util = require(‘util‘);
2 
3 console.log(util.inspect(process.memoryUsage()));

    这将打印:

{ rss: 4935680,
  heapTotal: 1826816,
  heapUsed: 650472 }

    heapTotalheapUsed 表示 V8 的内存使用。

process.nextTick(callback)

    在事件循环的下一次调用这个回调函数。这仅是 setTimeout(fn, 0) 的别名,它更有效率。典型地它在任何其他的 I/O 事件之前运行,但有一些例外。参看下面的 process.maxTickDepth
1 process.nextTick(function() {
2   console.log(‘nextTick callback‘);
3 });

    在开发 API 时若你想给用户机会去在对象被创建之后但在任何 I/O 发生之前分配事件监听器,这个函数是很重要的。

 1 function MyThing(options) {
 2   this.setupOptions(options);
 3 
 4   process.nextTick(function() {
 5     this.startDoingStuff();
 6   }.bind(this));
 7 }
 8 
 9 var thing = new MyThing();
10 thing.getReadyForStuff();
11 
12 // thing.startDoingStuff() gets called now, not before.

   保证 API 是100%同步的或100%异步的是非常重要的。考虑下面的例子:

1 // WARNING! DO NOT USE! BAD UNSAFE HAZARD!
2 function maybeSync(arg, cb) {
3   if (arg) {
4     cb();
5     return;
6   }
7 
8   fs.stat(‘file‘, cb);
9 }

    这个 API 是冒险的。如果你执行下面:

1 maybeSync(true, function() {
2   foo();
3 });
4 bar();

    那么不清楚到底 foo() 还是 bar() 先被执行。
    这个方法会更好:

1 function definitelyAsync(arg, cb) {
2   if (arg) {
3     process.nextTick(cb);
4     return;
5   }
6 
7   fs.stat(‘file‘, cb);
8 }

process.maxTickDepth

    ● 数字类型 默认值 = 1000
    传递给 process.nextTick 的回调函数通常会在当前的执行结束后才被调用,因此近似于尽快地同步调用一个函数。不进行任何检验,这将有可能饿死时间循环,阻止任何的 I/O 调用发起。
    考虑这样的代码:
1 process.nextTick(function foo() {
2   process.nextTick(foo);
3 });

    为了避免 Node 被一系列递归 nextTick 无限循环锁阻塞,它会延迟来让一些 I/O 每隔一段时间被执行。
    process.maxTickDepth 的值是 nextTick 调用 nextTick 回调函数的最大深度,以在允许其他形式的 I/O 发起前进行评估。

process.umask([mask])

    设置或读取进程的文件模式的创建掩码。子进程从父进程继承掩码。如果 mask 参数给出则返回就是掩码,否则返回当前的掩码。
1 var oldmask, newmask = 0644;
2 
3 oldmask = process.umask(newmask);
4 console.log(‘Changed umask from: ‘ + oldmask.toString(8) +
5   ‘ to ‘ + newmask.tostring(8));

process.uptime()

    Node 已经运行的秒数。

process.hrtime()

    返回 [秒,纳秒] 的元组数组形式的当前高精度真实时间。它相对于过去的任意时间。它不是跟一天中的某个时间有关,因此不会受制于时钟漂移。主要的用途是测量某间隔间的程序执行。
    你可以床底之前的调用结果给 process.hrtime() 来获得一个差异值,对基准和测量间隔很有用:
 1 var time = process.hrtime();
 2 // [ 1800216, 25 ]
 3 
 4 setTimeout(function() {
 5   var diff = process.hrtime(time);
 6   // [ 1, 552]
 7 
 8   console.log(‘benchmark took %d nanoseconds‘, diff[0] * 1e9 + diff[1]);
 9   // benchmark took 1000000527 nanaseconds
10 }, 1000);

 

Node.js API —— process(进程)

上一篇:C# 编写服务 Windows service


下一篇:Delphi的Hint介绍以及用其重写气泡提示以达到好看的效果