如何通过每次分支新的子进程来多次运行同一个jar文件

how to run same jar file multiple times by forking new child process every time?

本文关键字:运行 同一个 jar 文件 何通过 分支 子进程      更新时间:2023-10-16

我正在尝试写一个c++程序。该程序需要运行一些jar文件,每个jar文件运行两次。问题是程序只正确运行每个文件一次。在第二次我得到了一个错误的消息,好像虚拟机得到了一个错误的命令。但是,第一次运行jar文件的命令是相同的!!

这是我得到的红色错误消息的前几行。

Usage: java [-options] class [args...]
       (to execute a class)
   or  java [-options] -jar jarfile [args...]
       (to execute a jar file)
where options include:
    -d32      use a 32-bit data model if available
    -d64      use a 64-bit data model if available
    -client   to select the "client" VM
    -server   to select the "server" VM

这是我的代码。这是主文件:

#include <iostream>
#include <fstream>
#include <signal.h>
#include <string.h>
#include <time.h>
#include "StringParser.h"
#include "ShellCore.h"
using namespace std;
int main() {
    while (1) {
    char checkers_command[] = "java -jar /home/samer/Downloads/chkr.jar";
    char castle_command[] = "java -jar /home/samer/Downloads/cas.jar";
        int child_status;
        bool wait_bool = true;
        cout << "Run Batch Shell> ";
        cin.getline(input_command_line, 256);
        if (strcasecmp("exit", input_command_line) == 0) {
            cout << "The shell program will terminaten";
            exit(0);
        } else {
            char* commands;
            for (int var = 0; var < 4; ++var) {
                if (var % 2 == 0) {
                    commands = checkers_command;
                } else if (var % 2 == 1) {
                    commands = castle_command;
                } 
                char* arg_list_tokened[50];
                parse_command_line(arg_list_tokened, commands);
                spawn(arg_list_tokened[0], arg_list_tokened);
            if (wait_bool) {
                // The parent wait until the child finishes.
                cout << "The parent will wait for " << arg_list_tokened[0] << endl;
                wait(&child_status);
                if (WIFEXITED(child_status)) {
                    printf("The child process exited normally with exit code %dn",
                            WEXITSTATUS(child_status));
                } else {
                    printf("The child process exited abnormallyn");
                }
            }
        }
        cout << "donen";
    }
}
return 0;
}

这是Shellcore.cpp文件中的"spawn"方法:Shellcore.h包含了Shellcore.cpp所需的include。

#include "ShellCore.h"
pid_t child_pid;
int spawn(char* program_name, char** args) {
    child_pid = fork();
        if (child_pid != 0) {
        return child_pid;
    } else {
        execvp(program_name, args);
        // If the execvp return, this indicate that an error occurred.
        printf("From the spawn function in the parent process, execvp ERRORn");
        abort();
    }
}

很抱歉问题很长,代码也很长。谢谢预支:)

解析函数:
void parse_command_line(char* output_list[], char* command_line) {
    char * pch;
    int i = 0;
    pch = strtok(command_line, " &"");
    output_list[0] = pch;
    while (pch != NULL) {
        i++;
        pch = strtok(NULL, " &"");
        output_list[i] = pch;
    }
    output_list[++i] = NULL;
}

strtok()在调用时改变字符串。您将指针"命令"设置为checkers_command或castle_command,但strtok只是要覆盖指向后者的每个内存。如果你复制checkers/castle,而不是在调用解析函数之前指向它,那么每次通过循环,你都会得到一个新的checkers/castle副本。

有比strdup更好的方法,但为了简洁起见,您可以简单地这样做。如果您保留这种复制字符串的方法(不建议),请记住在完成后对返回的指针调用free(),否则将发生内存泄漏。

改成这样:

for (int var = 0; var < 4; ++var)
{
    if (var % 2 == 0)
    {
        //commands = checkers_command;
        commands = strdup(checkers_command);
    }
    else
        if (var % 2 == 1)
        {
            //commands = castle_command;
            commands = strdup(castle_command);
        }
   char* arg_list_tokened[50];
   parse_command_line(arg_list_tokened, commands);
   spawn(arg_list_tokened[0], arg_list_tokened);
   //............
}