Skip to content

进程通信的几种方式 ipc

  • 信号量 数字标记,不传递具体数据 例如信号量的初始值是 1,然后 a 进程来访问内存1的时候,我们就把信号量的值设为 0,然后进程b 也要来访问内存1的时候,看到信号量的值为 0 就知道已经有进程在访问内存1了,这个时候进程 b 就会访问不了内存1

  • 管道

    同步、两个进程之间、基于文件读写, a 进程给 b 数据,只能待 b 取了才返回

    • 匿名管道:netstat -tulnp | grep 8080, 把前一条命令的输出作为另一条的输入
    • 命名管道 mkfifo test echo "this is a pipe" > test cat < test cat 不去取 echo 就不返回,数据真的被拿走了
  • 消息队列

    异步、两个进程、不基于文件,无需等待 b 取就可以返回,不适合频繁读取数据,

  • 共享内存

    多个进程,多个进程可以读写,容易乱,需要自己控制顺序,通过进程号的增量

  • RPC 远程 http websocket

  • electron

    • 主->渲染 webContent.send、 ipcRender.on
    • 渲染->主 ipcRender.invoke、ipcMain.handler \ send on
  • node.js

    • child_process
      • spawn
        js
          const { spawn } = require('child_process');
          const child = spawn('pwd');
          child.stdout.pipe(process.stdout);
          child.stdout.on('data', function(data) {
            process.stdout.write(data);
          });
      • exec 同步执行 shell
        js
        const { exec, spawn } = require('child_process');
        exec('my.bat', (err, stdout, stderr) => {
          if (err) {
            console.error(err);
            return;
          }
          console.log(stdout);
        });
      • execFile 可执行文件
      • fork 执行 js

        可以将密集计算的逻辑放到单独的js文件中 然后再通过fork的方式来计算,等计算完成时再通知主进程计算结果,这样避免主进程繁忙的情况了。

        js
        const { fork } = require('child_process');
        const forked = fork('child.js');
        forked.on('message', (msg) => {
          console.log('Message from child', msg);
        });
        
        forked.send({ hello: 'world' });
        <!-- ---- -->
        
        process.on('message', (msg) => {
          console.log('Message from parent:', msg);
        });
        
        let counter = 0;
        
        setInterval(() => {
          process.send({ counter: counter++ });
        }, 1000);
        复制代码
    • cluster

在 MIT 许可下发布