java 根据pid 查看进程是否存活,杀掉进程,调用python

package com.hito.indai.standalone.service.algorithm;

import cn.hutool.core.util.RuntimeUtil;
import com.hito.indai.standalone.dto.ProcessDTO;
import com.hito.indai.standalone.entity.train.TrainModel;
import com.hito.indai.standalone.enums.model.TrainStatusEnum;
import com.hito.indai.standalone.exception.IndaiException;
import com.hito.indai.standalone.repository.train.TrainModelRepository;
import com.hito.indai.standalone.service.trian.ModelCacheSevice;
import com.hito.indai.standalone.util.ProccessUtil;
import com.sun.jna.Platform;
import io.micronaut.context.annotation.Value;
import lombok.extern.slf4j.Slf4j;

import javax.inject.Inject;
import javax.inject.Singleton;
import javax.transaction.Transactional;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.util.regex.Pattern.*;

/**
 * @author fuchanghai
 */
@Slf4j
@Singleton
public class ShellService {

    @Value("${micronaut.server.port}")
    private Integer myServerPort;

    @Inject
    private TrainModelRepository trainModelRepository;

    private static HashMap<String, Process> processHashMap = new HashMap<>();

    public String getGPU() throws IOException {
        Process process = null;
        try {
            if (Platform.isWindows()) {
                process = Runtime.getRuntime().exec("nvidia-smi.exe");
            } else if (Platform.isLinux()) {
                String[] shell = {"/bin/bash", "-c", "nvidia-smi"};
                process = Runtime.getRuntime().exec(shell);
            }

            process.getOutputStream().close();
        } catch (IOException e) {
            e.printStackTrace();
            throw new IndaiException("显卡不存在或获取显卡信息失败");
        }

        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));

        StringBuffer stringBuffer = new StringBuffer();
        String line = "";
        while (null != (line = reader.readLine())) {
            stringBuffer.append(line + "\n");
        }

        return stringBuffer.toString();
    }

    public int startTrain(TrainModel trainModel, String configFilePath, String pictureJsonFilePath, int time) {
        String doc = "\"" + getAlgorithmAbsolutePath() + File.separator + "classify_train.exe\" " + " --config_file=\"" + configFilePath + "\"  --callback_ip=localhost " + " --json_file=\"" + pictureJsonFilePath + "\" --callback_port=" + myServerPort;
        log.info(doc);
        Process process = null;
        int pid = 0;
        try {
            process = Runtime.getRuntime().exec(new String[]{"cmd", "/c", doc});
            pid = ProccessUtil.getPid(process);
            //此处先执行业务 再打印流,因为流是阻塞的,否则只有流打印完才能执行业务
            beforeCallAlg(trainModel,pid,time,process);
            String str = null;
            BufferedReader buffer = new BufferedReader(new InputStreamReader(process.getErrorStream(), "gbk"));
            while ((str = (buffer.readLine())) != null) {
                log.info("输出流:" + unicodeToString(str));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return pid;
    }

    public int startDetectionOrSegmentTrain(TrainModel trainModel, String configFilePath, String trainJsonFile,String validJsonFile, int time,String taskType) {
        String doc = "\"" + getAlgorithmAbsolutePath() + File.separator + "instance_train.exe\" " +
                " --config_file=\"" + configFilePath +
                "\"  --callback_ip=localhost " +
                " --train_json_file=\"" + trainJsonFile +
                "\" --valid_json_file=\"" + validJsonFile +
                "\" --task_type=\"" + taskType +
                "\" --callback_port=" + myServerPort;
        log.info(doc);
        Process process = null;
        int pid = 0;
        try {
            process = Runtime.getRuntime().exec(new String[]{"cmd", "/c", doc});
            pid = ProccessUtil.getPid(process);
            beforeCallAlg(trainModel,pid,time,process);
            String str = null;
            BufferedReader buffer = new BufferedReader(new InputStreamReader(process.getErrorStream(), "gbk"));
            while ((str = (buffer.readLine())) != null) {
                log.info("输出流:" + unicodeToString(str));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return pid;
    }

    //事务要细粒到这不然会被流阻塞
    @Transactional(rollbackOn = Exception.class)
    public void beforeCallAlg(TrainModel trainModel,Integer pid,Integer time ,Process process){
        trainModel.setProcessId(pid);
        trainModel.setTrainStatus(TrainStatusEnum.RUNNING.code());
        trainModel.setBeginTrainTime(new Date());
        trainModelRepository.update(trainModel);
        ProcessDTO processDTO = new ProcessDTO();
        processDTO.setBeginTime(trainModel.getBeginTrainTime());
        processDTO.setTime(time + 1);
        processDTO.setProcess(process);
        processDTO.setStart(false);
        ModelCacheSevice.processMap.put(trainModel.getId(), processDTO);
    }

// 根据pid 杀死算法进程
    public void stopTrain(int pid) {
        //使用WMIC获取CPU序列号
        Process process = null;
        try {
            process = Runtime.getRuntime().exec("taskkill /pid " + pid + " -t -f");
            process.getOutputStream().close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


//根据pid 查看算法进程是否存活
    public boolean processIsAlive(Integer processId) {
        String docCommand = "tasklist | findstr " + processId;
        String s = RuntimeUtil.execForStr(new String[]{"cmd", "/c", docCommand});
        if (s.length() == 0) {
            return false;
        }
        return true;
    }

    public String getAlgorithmAbsolutePath() {

        // jar包运行
        File jarFile = new File(System.getProperty("java.class.path"));
        String algorithmPath = jarFile.getParent() + File.separator + "algorithm";

        // 本地调试
        /*File file = new File("src");
        String algorithmPath = new File(file.getAbsolutePath()).getParentFile().getAbsolutePath() + File.separator + "algorithm";*/
       /* String algorithmPath = "C:\\Program Files\\ZhiTu\\resources\\libs\\algorithm";*/
        log.info("算法代码绝对路径:" + algorithmPath);
        return algorithmPath;
    }

    public static String unicodeToString(String str) {
        Pattern pattern = compile("(\\\\u(\\p{XDigit}{4}))");
        Matcher matcher = pattern.matcher(str);
        char ch;
        while (matcher.find()) {
            ch = (char) Integer.parseInt(matcher.group(2), 16);
            str = str.replace(matcher.group(1), ch+"" );
        }
        return str;
    }
}

这里用的是micronaut 不是springboot

todo 流关闭最好放入finally中,需要使用嵌套事物,解决一致性问题

### Python `multiprocessing.Process` 的使用方法及示例 #### 方法概述 在 Python 中,`multiprocessing.Process` 是实现进程的核心类之一。它允许开发者通过创建独立的子进程来执行特定的任务[^2]。每个子进程拥有自己的内存空间,因此不会与其他进程共享全局变量。 以下是 `Process` 类的主要参数说明: - **target**: 可调用的对象(通常是函数),表示新进程中要运行的目标任务。 - **args**: 传递给目标函数的位置参数元组。 - **kwargs**: 传递给目标函数的关键字参数字典。 - **daemon**: 设置守护进程标志,默认为 False。如果设置为 True,则当父进程终止时,子进程会自动被销毁而不等待其完成。 #### 示例代码 下面是一个简单的例子展示如何使用 `multiprocessing.Process` 创建和启动一个新的进程: ```python from multiprocessing import Process import os def info(title): print(f"{title} - PID: {os.getpid()}") def f(name): info('function f') print(f'hello {name}') if __name__ == '__main__': info('main line') p = Process(target=f, args=('bob',)) p.start() p.join() # 主程序在此处阻塞直到子进程结束 ``` 在这个例子中,我们定义了一个名为 `f` 的函数作为子进程中的主要逻辑,将其传入到 `Process` 实例化过程中。最后通过调用 `p.start()` 启动这个新的进程[^3]。 #### 守护进程行为分析 关于守护进程的行为特性,在某些场景下可能需要注意。例如,当设置了 `p.daemon=True` 且父进程提前退出的情况下,即使子进程尚未完成工作也会立即被强制关闭。这可以通过如下实验验证: ```python from multiprocessing import Process import time def worker(): try: while True: print("Worker is running...") time.sleep(1) except KeyboardInterrupt: print("Stopping gracefully.") if __name__ == "__main__": process = Process(target=worker) process.daemon = True # 设定为守护模式 process.start() time.sleep(5) # 让主线程短暂休眠几秒后再退出 print("Main process exiting.") ``` 上述脚本展示了当主进程存活五秒钟之后便自行终结的情形下,尽管子进程仍在尝试循环输出日志消息,但由于它是作为一个守护进程存在,故随着主进程消亡而被迫停止运作。 #### 数据共享解决方案 对于需要跨不同进程间交换数据的需求来说,单独依靠基本类型的副本拷贝显然是不够高效的;此时可借助于 `multiprocessing.Manager` 提供的功能构建更为复杂的结构体来进行通信与同步控制[^4]。比如下面的例子演示了怎样利用管理器生成一个可供多方读写的列表容器: ```python from multiprocessing import Manager, Process def add_items(lst): lst.append("Item added by subprocess!") if __name__ == '__main__': with Manager() as manager: shared_list = manager.list(['Initial item']) proc = Process(target=add_items, args=(shared_list,)) proc.start() proc.join() print(shared_list) ``` 这里采用了上下文管理的方式确保资源能够得到妥善释放的同时也简化了异常处理流程的设计复杂度。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值