简体   繁体   English

从C程序中运行C程序

[英]Run a C program from within a C program

The question pretty much explains itself I have three different C programs and to try and compare their efficiency I tried to test their runtime by making them run several times varying their parameter (which is proportional to time taken) and write how long it takes each program to run for certain parameter (so later i can plot the results). 这个问题几乎可以自我解释。我有三个不同的C程序,为了比较它们的效率,我试图通过使它们运行多次以改变其参数(与所花费的时间成比例)并记录每个程序花费多长时间来测试它们的运行时间。为某些参数运行(以便稍后我可以绘制结果)。

The following is my code 以下是我的代码

   # include <stdio.h> 
    # include <stdlib.h>
    # include <math.h>
    # include <time.h>  

   int main(void){

    int i;
    struct timeval bni, bmi, bfi, bnf, bmf, bff;
    FILE *in;
    char filename1[30] = "shuff.dat";
    int a1,a2,b1,b2,c1,c2;
    char command[100];

    in = fopen(filename1, "w");
    //for(i = 0; i<=100000; i +=100){
    for(i = 0; i<=10; i +=1){

        if (snprintf(command, sizeof(command), "./barajas_n.x %d", i) < sizeof(command)){
        a1 = gettimeofday(&bni , NULL);
        system(command);
        a2 = gettimeofday(&bnf , NULL);
        }

        if (snprintf(command, sizeof(command), "./barajas_m.x %d", i) < sizeof(command)){
        b1 = gettimeofday(&bmi , NULL);
        system(command);
        b2 = gettimeofday(&bmf , NULL);
        }

        if (snprintf(command, sizeof(command), "./barajas_fy.x %d", i) < sizeof(command)){
        c1 = gettimeofday(&bfi , NULL);
        system(command);
        c2 = gettimeofday(&bff , NULL);
        }
        fprintf(in, "%d %d %d %d \n", i, (a2-a1),(b2-b1),(c2-c1));
    }
    fclose(in);
}

I get the following message on the terminal window: 我在终端窗口上收到以下消息:

错误信息

Which means this program is running all of its steps, only not correctly executing the programs I want to time. 这意味着该程序正在运行其所有步骤,只是没有正确执行我想定时的程序。

I've tested all three programs individually in the terminal like this 我已经像这样在终端中分别测试了所有三个程序

./barajas_*.x i
  1. Can someone please tell me why system() is taking it's input as a directory and, 有人可以告诉我为什么system()将输入作为目录,并且
  2. how to tell system() it to stop taking it as a directory and execute it? 如何告诉system()停止将其作为目录并执行它?

EDIT: After a long discusion in a chat room the problem was as said by Jonathan Leffler: " a mismatch between the actual command name that existed and the command name that the program was attempting to run." 编辑:在聊天室中进行了长时间讨论之后,该问题如乔纳森·莱夫勒(Jonathan Leffler)所说:“存在的实际命令名与程序试图运行的命令名之间不匹配。”

The actual question is answered by iharob's contribution, for anyone interested the snippet he provided should work if the command name matches the command name being run by the program. 实际的问题由iharob的贡献来回答,对于感兴趣的任何人,只要命令名与程序正在运行的命令名匹配,他提供的代码段都应该起作用。

The system() function takes only one argument of type const char * , if you need to build the command try with snprintf() , like this system()函数仅接受const char *类型的一个参数,如果您需要使用snprintf()构建命令try,例如这样

char command[100];

if (snprintf(command, sizeof(command), "barajas_n.x %d", i) < sizeof(command))
{
    a1 = gettimeofday(&bni , NULL);
    system(command);
    a2 = gettimeofday(&bfi , NULL);
}

also, the return value of gettimeofday() is not useful for calculating the time difference. 同样, gettimeofday()的返回值对于计算时间差也没有用。 It's just to check errors, you can get the elapse time using this function 只是检查错误,您可以使用此功能获得经过时间

float elapsed_time(struct timeval *end, struct timeval *start)
{    
    struct timeval result;
    if (end->tv_usec - start->tv_usec > 1.0E6)
    {
        double adjust;

        adjust          = (end->tv_usec - start->tv_usec) / 1.0E6;
        start->tv_usec += 1.0E6 * adjust;
        start->tv_sec  -= adjust;
    }
    result.tv_sec  = end->tv_sec  - start->tv_sec;
    result.tv_usec = end->tv_usec - start->tv_usec;

    return result.tv_sec + result.tv_usec / 1.0E6;
}

and then to print the elapsed time 然后打印经过的时间

printf("Elapsed time: %f\n", elapsed_time(&bni, &bfi);

As the other answer mentioned you need to add a slash to execute the programs, ./programname instead of .programname , but this is another solution: 正如提到的其他答案一样,您需要添加一个斜杠来执行程序,。/ ./programname而不是.programname ,但这是另一种解决方案:

#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <unistd.h>

#include <sys/time.h>
#include <time.h>

/* This function, just calculates the difference in seconds, between end and start */
float elapsed_time(struct timeval *end, struct timeval *start)
{
    struct timeval result;
    if (end->tv_usec - start->tv_usec > 1.0E6)
    {
        float adjust;

        adjust          = (end->tv_usec - start->tv_usec) / 1.0E6;
        start->tv_usec += 1.0E6 * adjust;
        start->tv_sec  -= adjust;
    }
    result.tv_sec  = end->tv_sec  - start->tv_sec;
    result.tv_usec = end->tv_usec - start->tv_usec;

    return result.tv_sec + result.tv_usec / 1.0E6;
}

/* this function will execute the command and wrap the system call
 * with 'gettimeofday()' so you can return the elapsed time while
 * the called program was running.
 *
 * It also builds the command string with the right parameter. 
 */
float run_command_and_return_time(const char *const program, int parameter)
{
    char           command[100];
    struct timeval start;
    struct timeval end;
    int            result;
    /* check that sprintf didn't need more characters */
    result = snprintf(command, sizeof(command), "%s %d", program, parameter);
    if ((result >= sizeof(command)) || (result < 0))
        return -1.0;
    gettimeofday(&start, NULL);
    system(command);
    gettimeofday(&end, NULL);

    return elapsed_time(&end, &start);
}

int
main(int argc, char **argv)
{
    char        cwd[PATH_MAX];
    const char *filename;
    FILE       *output;

    filename = "shuff.dat";
    output   = fopen(filename, "w");
    if (output == NULL)
        return -1;
    /* get the current working directory */
    getcwd(cwd, sizeof(cwd));
    /* add the cwd to the PATH variable, so your barajas_*.x programs are found,
     * this way you don't need the ./bara... anymore, just bara... will do it.
     */
    setenv("PATH", cwd, 1);
    /* from here it's pretty evident what the program does */
    for (int i = 0 ; i < 10 ; ++i)
    {
        float a, b, c;

        a = run_command_and_return_time("barajas_n.x", i);
        b = run_command_and_return_time("barajas_m.x", i);
        c = run_command_and_return_time("barajas_fy.x", i);

        fprintf(output, "%d %f %f %f \n", i, a, b, c);
    }
    /* don't forget to close the output file */
    fclose(output);

    return 0;
}

I note that your code currently reads: 我注意到您的代码当前显示为:

if (snprintf(command, sizeof(command), ".barajas_n.x %d", i) < sizeof(command)){

It looks to me like you're missing a slash in that: 在我看来,您在其中缺少斜线:

if (snprintf(command, sizeof(command), "./barajas_n.x %d", i) < sizeof(command)){

If that's just a typo, then one remaining problem is that gettimeofday() always returns 0: 如果这只是一个错字,那么剩下的问题就是gettimeofday()总是返回0:

The gettimeofday() function shall return 0 and no value shall be reserved to indicate an error. gettimeofday()函数应返回0,并且不应保留任何值来指示错误。

Any elapsed time is found by computation on the struct timeval structures, more or less as shown in the answer by iharob . 通过计算struct timeval结构,可以找到任何经过的时间,或多或少,如iharob答案所示。

Post-chat synopsis 聊天后简介

I invited Carlos to chat with me. 我邀请卡洛斯和我聊天

After a bit of discussion in chat and seeing the actual results of running the program, we discovered that the problem was a typo — a mismatch between the actual command name that existed and the command name that the program was attempting to run. 在聊天中进行了一些讨论并查看了运行该程序的实际结果后,我们发现问题是一个错字-存在的实际命令名与该程序试图运行的命令名之间不匹配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM