Java父子进程通信(标准输入输出)

参考链接

https://blog.csdn.net/qq_36066039/article/details/117523496

应用场景

B进程负责处理数据,结果输出在标准输出中,A进程作为B的父进程去启动B进程,A进程可以获取到B进程的stdout,stderr。
1、解耦:假设B进程是java语言开发,那么A进程可以是shell,可以是c++也可以是python,这样就做到了解耦。原理就是父子进程通信, 这种通信方式是pip管道通信。 对进程通信想要详细了解的同学可以去查阅相关资料,展示代码demo父子进程都是java版本。
2、防止系统崩溃:个人在一次开发中,需要用到C++开发的方法,但是其有Bug,当数据异常时会导致进程崩溃(C++读到空指针了)。此时系统就会直接退出,需要重新启动,这在生产上是大事故,是无法容忍的。此时的解决方案就是开辟一个新的进程去处理数据,这样即使数据异常,core的也是新的进程,对系统正在运行的进程不会有影响。

父进程代码

import java.io.*;
//process.getInputStream是用来读取控制台命令结果的   控制台数据的流入可以往System.out
//process.getOutputStream是用来往控制台写入数据的   此结果可以由System.in端读出
public class Father {
    public static void main(String[] args) throws IOException {
        Runtime run = Runtime.getRuntime();
//      获取java执行命令所在的位置
        String java = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
//      获取类加载的时候的加载的class文件的路径,返回结果是一个string,多个路径之间用";"分割.
        String cp = "\"" + System.getProperty("java.class.path");
//      获取当前程序的class文件所在的位置
        cp += File.pathSeparator + ClassLoader.getSystemResource("").getPath() + "\"";
//        java -cp 命令   (这是运行class文件的命令,会将class文件载入jvm)
        String cmd = java + " -cp " + cp + " connect.test2.Child";
//        开启一个子进程
        Process child_process = run.exec(cmd);
//      往子进程写数据
        DataOutputStream dataOutputStream = new DataOutputStream(child_process.getOutputStream());
        dataOutputStream.writeUTF("hello child");
        dataOutputStream.close();//注意这个close方法,写完之后记得关闭
        System.out.println("写出成功");
//     父进程获取子进程控制台数据
        DataInputStream dataInputStream= new DataInputStream(child_process.getInputStream());
        while (true){
            String line = dataInputStream.readUTF();
            System.out.println(line);
            if(line.contains("end")){
                break;
            }
        }
        dataInputStream.close();
    }
}

子进程代码

import java.io.*;
//其实System.out是一个流对象:源码:public class PrintStream extends FilterOutputStream
//System.out.println("")其实是PrintStream.print()
public class Child {
    public static void main(String[] args) throws IOException, InterruptedException {
//        子进程获取父进程的数据
        DataInputStream dataInputStream =new DataInputStream(System.in);
        String line = dataInputStream.readUTF();
//        将子进程的数据输入到子进程的控制台
        DataOutputStream dataOutputStream = new DataOutputStream(System.out);
        dataInputStream.close();
        for(int i=0;i<2;i++) {
//            数据将流入当前进程的控制台也就是System.out
            dataOutputStream.writeUTF("hi" + line);
        }
        dataOutputStream.writeUTF("end");
        dataOutputStream.close();
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Linux父子进程间通信可以使用以下几种方法: 1. 管道(pipe) 2. 信号(signal) 3. 共享内存(shared memory) 4. 消息队列(message queue) 5. 信号量(semaphore) 6. 套接字(socket) ### 回答2: 在Linux系统中,进程不仅可以与其他进程进行通信,还可以与其父子进程进行通信父子进程是指一个进程可以通过fork调用创建一个新的进程,其中原进程为父进程,新进程为子进程。父子进程之间的通信主要是通过管道来实现的。 所谓管道,就是一个数据通道,可以使得数据从一个进程流入到另一个进程中。在Linux系统中,管道主要有两种类型:匿名管道和命名管道。匿名管道是指在进程之间创建的一种特殊文件,它没有文件名,只能用于父进程和其子进程之间的通信。而命名管道也叫有名管道,是一种系统级的FIFO文件,可用于任意进程间的通信。 在Linux系统中,父进程和子进程之间通信的一般步骤如下: 1. 创建一个管道,使用pipe()函数。 2. 创建子进程,使用fork()函数。 3. 在子进程中,关闭管道的写入端,即用close()函数关闭fd[1]。 4. 在父进程中,关闭管道的读取端,即用close()函数关闭fd[0]。 5. 父进程向管道中写入数据,使用write()函数将数据写入fd[1]。 6. 子进程从管道中读取数据,使用read()函数从fd[0]中读取数据。 7. 父进程和子进程需要在完成通信后关闭管道,即分别使用close()函数关闭fd[0]和fd[1]。 父子进程之间的通信可以用于各种场景下,例如:进程间传递数据、子进程返回值给父进程、父进程传递命令给子进程等等。总之,在Linux系统中,管道是一种很有用的进程通信方法,能够使得父子进程之间的通信变得轻松简单,而且无需使用外部的库或工具。 ### 回答3: Linux是一种使用广泛的操作系统,其优势之一是其提供了多种通信机制,包括父子进程通信父子进程间的通信Linux中进程间通信的一种常见方式。 在Linux中,通过fork()系统调用可以实现父进程创建子进程。在子进程中,可以使用exec函数进行新程序的加载。父子进程之间通过进程标识符(PID)进行通信,父进程和子进程拥有各自独立的地址空间和文件描述符表。 父进程可以通过创建匿名管道或命名管道来向子进程发送数据,也可以通过IPC通信、共享内存等方式进行通信。当父子进程同时访问共享资源时,需要使用信号量或互斥锁等同步机制进行互斥。 子进程可以通过exit()函数向父进程发送退出信号。子进程也可以使用SIGCHILD信号告知父进程它的状态发生了变化。 在使用父子进程通信时,需要注意的是,由于父子进程之间的关系是一一对应的,因此如果有多个子进程需要与父进程进行通信,则需要针对每个子进程分别进行通信处理。 总之,Linux父子进程通信是非常有用的一种进程间通信方式,既可以实现单一方向的通信,也可以实现双向通信,非常适合在多进程程序中使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值