首页 > 解决方案 > 程序的编译是否在执行前将一些数据存储在缓存中?(C,Linux)

问题描述

程序的编译是否在执行前将一些数据存储在缓存中?

我在 Linux 中编写了一个 C 程序,它在一个线程中启动 Sublime Text,并在另一个线程中进行手动系统调用。(我将在最后解释为什么我这样做,因为这与这个问题无关)
我正在使用getrusage来测量 I/O 的数量。

我的问题是,编译后 I/O 输入的数量减少了很多。换句话说,如果我在编译和执行之间不释放缓存和内存,I/O 的数量就会减少很多。为什么以及如何发生这种情况?请参阅以下案例。

案例 A - 1) 编译 2) 执行

> $ gcc pmulti.c -o pmulti    
> $ ./pmulti

<result>
 I/O Input: 632 Output: 0

案例 B 1) 编译 2)释放内存和缓存 3) 执行

> $ gcc pmulti.c -o pmulti
> # free && sync && echo 3 > /proc/sys/vm/drop_caches && free    
> $ ./pmulti

<result>
I/O Input: 1400 Output: 0

如您所见,输入的数量是 Case A < Case B。这意味着在其编译过程中发生了某些事情,并且受到释放缓存和内存的影响。

为什么以及如何发生这种情况?我在哪里可以了解更多信息?

完整代码:https ://pastebin.com/R6v00LLW

我的代码的缩写版本:

struct rusage usage;

void *func1(void *vargp)
{

    /*     Manual System Calls Here     */


    return NULL;
}

void *func2(void *vargp)
{

    long pid;
    int stat_loc;

    if ((pid = (long) fork()) == 0){
        //Format string for execvp here
        char s[] = "/opt/sublime_text/sublime_text";    
        char* separator = " ";
        char* argv[64];
        int argc = 0;
        char* tmp;  
        argv[argc] = strtok_r(s, separator, &tmp);
        while( argv[argc] != NULL){
            argc+=1;
            argv[argc] = strtok_r(NULL, separator, &tmp);
        }
        execvp(argv[0],argv); 
    }
    else {
        waitpid(pid, & stat_loc, WUNTRACED);
    }  

    return NULL;
}

int main()
{    
    pthread_t thread_id[2];
    pthread_create(&thread_id[1], NULL, func2, NULL);
    pthread_create(&thread_id[0], NULL, func1, NULL);
    pthread_join(thread_id[0], NULL);
    pthread_join(thread_id[1], NULL);

    getrusage(RUSAGE_SELF, &usage);
    printf("Input: %ld Output: %ld\n", usage.ru_inblock, usage.ru_oublock);

    exit(0);
}

该计划的目的:

我试图想出一些方法来改善应用程序的启动/加载时间。我在想也许我可以通过使用多线程进行手动系统调用来加快这个过程。我只是一名学生,所以我的方法可能完全错误。我已经可以想到为什么这不起作用,因为线程是并发执行的,可能会在这些系统调用之前调用 execvp :(

func1 进行手动系统调用,而 func2 执行 Sublime Text。

这是我在操作系统课上的学期项目的一部分。我正在通过 Windows 10 上的 VirtualBox 在 Linux MintMate 上运行它。

标签: clinuxmultithreadingterminalgetrusage

解决方案


编译器刚刚完成对可执行文件的写入。结果,文件的许多,甚至可能是大多数页面可能仍然在缓冲区缓存中,并且在运行程序时不需要从磁盘读回。


推荐阅读