如何通过每次分叉新的子进程多次运行相同的jar文件?

时间:2011-04-22 10:37:05

标签: c++ linux jvm executable-jar fork

我正在尝试编写一个c ++程序。 该程序需要运行一些jar文件,运行每个jar文件两次。 问题是程序只运行一次正确的文件。 在第二次我收到错误消息,好像VM得到了错误的命令。但是,它是第一次运行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 terminate\n";
            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 %d\n",
                            WEXITSTATUS(child_status));
                } else {
                    printf("The child process exited abnormally\n");
                }
            }
        }
        cout << "done\n";
    }
}
return 0;
}

这是Shellcore.cpp文件中的“spawn”方法: Shellcore.h包含Shellcore.cpp所需的包含。

#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 ERROR\n");
        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;
}

1 个答案:

答案 0 :(得分:2)

当你调用它时,

strtok()会改变你的字符串。您将指针“commands”设置为checkers_command或castle_command,但strtok只会覆盖后者每个指向的内存。如果您在调用解析函数之前复制跳棋/城堡而不是仅仅指向它,那么每次循环时都会有一个新的副本/城堡。

除了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);

   //............

}