Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

child_precess #47

Open
vivatoviva opened this issue Jun 2, 2019 · 0 comments
Open

child_precess #47

vivatoviva opened this issue Jun 2, 2019 · 0 comments
Labels

Comments

@vivatoviva
Copy link
Owner

文档部分

  • 创建异步进程

    • spawn(基础)
    • exec:衍生一个shell并在shell中执行命令,当完成则将stdoutstderr传给回调函数
    • execFile:类似于exec,但是默认情况下这个命令会直接衍生命令且默认衍生shell(可以开启),因此不支持IO重定向和文件通配等行为
    • fork:衍生一个新的nodejs进程,并建立IPC通道来调用指定的模块,该通道允许在父进程与子进程之间发送消息,衍生的Nodejs进程独立于父进程,但两者之间建立的IPC通道除外,每个进程都有自己的内存,都带有自己的V8实例,由于需要额外的资源分配,因此不建议衍生大量的Node.js子进程
  • 创建同步进程

    • spawnSync(基础)
    • execFileSync
    • execSync

Child_process.exec()和child_process.execFile()之间重要区别可能因平台异。因为在unix类型的操作系统上,child_prcessFile()可以更加高效,因为默认情况下,不会衍生shell,但是在window上,.bat 和 .cmd 文件在没有终端的情况下不能自行执行,因此无法使用child_process.execFile()启动, 在 Windows 上运行时,可以使用带有 shell 选项集的 child_process.spawn()、或使用 child_process.exec() 或通过衍生 cmd.exe 并将 .bat.cmd 文件作为参数传入(也就是 shell 选项和 child_process.exec() 所做的)。 在任何情况下,如果脚本文件名包含空格,则需要加上引号,在window中执行这些命令需要注意

  • ChildPrecess类型
    • 事件
      • close事件
      • disconnect事件
      • error事件,下面三种情况可能触发
        • 无法衍生进程
        • 无法杀死进程
        • 向子进程发送信息失败
      • exit事件
      • message事件
    • 属性
      • channel:返回子进程IPC的引用
      • connected:表明子进程可以接受和发送消息
      • killed:这种为true的情况表明子进程收到kill信号,但是并不表明子进程已被终止
      • pid
      • stderr
      • stdin
      • stdio
      • stdout
    • 方法
      • disconnect():关闭父进程与子进程的IPC通道,process.disconnect()同理
      • kill():向子进程发送信号
      • ref():还原已被移除的 子进程计数,父进程需要在退出之前等待子进程的退出
      • send():这个是父进程调用,同理也有一个process.send方法是子进程传递消息给父进程传递消息,这个方法比较重要,因为集群就是在 这个基础上封装的,所以理解其这个很重要
      • unref():让父进程移除子进程计数
  • maxBuffer和Unicode
    • 和buffer有关的参数,因为stdin和stdout是一个Buffer,用户这个值来表示允许的最大字节数,如果超过这个值,子进程会被终止

理解部分

1. stdinstdoutstderrstdio四者关系

  • stderr::返回子进程的stderr可读流

  • stdin:返回子进程的可写流

  • stdio:一个到子进程的管道的稀疏数组,

  • stdout:一个到子进程的可读流

2. 什么是IPC通道

进程间通信,简写为IPC:指的是两个或两个以上进程(或线程)之间进行数据或者信号交互的技术方案

(1) 文件

(2) 信号

(3) 套接字(socket)

(4) Unix域套接字(Unix domain socket)

用于在同一台机器上运行的进程之间的通信。虽然因特网域套接字可用于同一目的,但UNIX域套接字的效率更高。UNIX域套接字仅仅复制数据;它们并不执行协议处理,不需要添加或删除网络报头,无需计算检验和,不要产生顺序号,无需发送确认报文。

#####(5) 消息队列(message queue)

类似于套接字的数据流,但消息有自己的结构,它允许多个进程只需要读写消息队列,而不需要直接相互连接。

(6) 管道(pipe)

管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。

(7)命名管道(Named pip或FIFO)

命名管道可在同一台计算机的不同进程之间或在跨越一个网络的不同计算机的不同进程之间,支持可靠的、单向或双向的数据通信。

#####(8) 共享内存(Shared memory)

允许多个进程访问同一个内存块,该内存块作为一个共享缓冲区,供进程间相互通信。

(9) 消息传递(Message passing)

一般在并发模型中,允许多个程序使用消息队列或者托管通道通信。

(10) 内存映射文件

类似于标准的文件,内存映射文件映射到RAM,可以直接对内存地址进行更改,而不是更改输出流。

3. 信号signal种类

(3.1) 信号种类

linux中总共定义了64种信号,分为两类:可靠信号与不可靠信号,前32中信号为不可靠信号,后32种为可靠信号

  • 不可靠信号: 不支持排队,信号可能会丢失,信号取值区间在1~31
  • 可靠信号:也称之为实时信号,支持排队,信号不会丢失,发送多少次,就可以收到多少次,信号取值区间为32~64

使用kill -l可以查看所有的signal信号

取值 名称 解释 默认动作
1 SIGHUP 挂起
2 SIGINT 中断
3 SIGQUIT 退出
4 SIGILL 非法指令
5 SIGTRAP 断点或陷阱指令
6 SIGABRT abort发出的信号
7 SIGBUS 非法内存访问
8 SIGFPE 浮点异常
9 SIGKILL kill信号 不能被忽略、处理和阻塞
10 SIGUSR1 用户信号1
11 SIGSEGV 无效内存访问
12 SIGUSR2 用户信号2
13 SIGPIPE 管道破损,没有读端的管道写数据
14 SIGALRM alarm发出的信号
15 SIGTERM 终止信号
16 SIGSTKFLT 栈溢出
17 SIGCHLD 子进程退出 默认忽略
18 SIGCONT 进程继续
19 SIGSTOP 进程停止 不能被忽略、处理和阻塞
20 SIGTSTP 进程停止
21 SIGTTIN 进程停止,后台进程从终端读数据时
22 SIGTTOU 进程停止,后台进程想终端写数据时
23 SIGURG I/O有紧急数据到达当前进程 默认忽略
24 SIGXCPU 进程的CPU时间片到期
25 SIGXFSZ 文件大小的超出上限
26 SIGVTALRM 虚拟时钟超时
27 SIGPROF profile时钟超时
28 SIGWINCH 窗口大小改变 默认忽略
29 SIGIO I/O相关
30 SIGPWR 关机 默认忽略
31 SIGSYS 系统调用异常
(3.2) 信号产生
  • 硬件方式
    • 用户输入
    • 硬件异常:CPU检测到内存中非法访问异常,通知内核生成相应信号,并发送给发送事件的进程
  • 软件方式
    • 软件调用kill()、raise()、sigqueue()、alarm()、setitimer()、abort()
(3.3) 信号处理

内核处理进程收到的signal是在当前进程的上下文,故进程必须是Running状态。当进程唤醒或者调度后获取CPU,则会从内核态转到用户态时检测是否有signal等待处理,处理完,进程会把相应的未决信号从链表中去掉。

处理时机:内核态-> signal信号处理 -> 用户态

  • 内核态:signal信号不起作用
  • 用户态:signal所有未被屏蔽的信号都处理完毕
  • 当取消屏蔽时,会在下一次内核转用户态的过程中执行

4. 如何实现多进程之间的,cluster底层实现?

下个模块重点探讨下这个问题

参考

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant