【问题标题】:how to run same jar file multiple times by forking new child process every time?如何通过每次分叉新的子进程来多次运行同一个 jar 文件?
【发布时间】:2011-04-22 10:37:05
【问题描述】:

我正在尝试编写一个 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 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;
}

【问题讨论】:

  • 我认为问题出在 parse_command_line 或您对它的使用上。你能粘贴那个函数的源代码吗?
  • 我不这么认为,因为解析功能第一次适用于每个 jar 文件。
  • 是的,我的建议是第二次不起作用! C++ 不是 Haskell - 函数不一定每次都像在 Haskell 中那样做同样的事情!

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


【解决方案1】:

strtok() 在您调用它时会更改您的字符串。您将指针“命令”设置为 checkers_command 或 castle_command 但 strtok 只会覆盖指向后者的内存。如果您在调用 parse 函数之前复制 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);

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

}

【讨论】:

  • 非常感谢,我忘记了 strtok 的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-24
  • 1970-01-01
  • 2016-09-22
  • 2013-11-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多