如果我在运行可执行文件时重新编译它会发生什么?操作系统在启动运行该文件时是否会将所有的内容都读入内存,因此它永远不会读取新的可执行文件?还是它会读取新的可执行文件中认为未更改的部分,从而引起可能未定义的行为?
如果我有一个脚本在循环中重复调用一个可执行文件,并且在脚本运行时重新编译了这个可执行文件。那么可以保证循环的未来迭代将调用新的可执行文件,只有在进行切换时正在进行中的调用结果可能会受到损坏吗?
我的操作系统是Linux,但我也想知道在Windows上会发生什么。
如果我在运行可执行文件时重新编译它会发生什么?操作系统在启动运行该文件时是否会将所有的内容都读入内存,因此它永远不会读取新的可执行文件?还是它会读取新的可执行文件中认为未更改的部分,从而引起可能未定义的行为?
如果我有一个脚本在循环中重复调用一个可执行文件,并且在脚本运行时重新编译了这个可执行文件。那么可以保证循环的未来迭代将调用新的可执行文件,只有在进行切换时正在进行中的调用结果可能会受到损坏吗?
我的操作系统是Linux,但我也想知道在Windows上会发生什么。
因为这是一个传统的编译器,它会生成一个可执行文件,让我们在Linux上跟随它。
首先要知道的是,Linux文件名并不直接指向文件,而是指向一个目录条目,这个目录条目与文件名无关。实际上,一个文件并不需要有文件名,但如果没有文件名将很难引用它。
如果一个进程正在使用一个文件,而你替换或删除了它,该进程将通过它的目录条目继续使用该文件。任何新的进程使用该文件或查找它都将得到新版本(如果您替换了它)或找不到它(如果你删除了它)。一旦所有进程都完成了对旧文件的操作,它将从文件系统中删除。
因此,如果你重新编译并创建了一个同名的新可执行文件,你不会影响正在运行的进程。它将继续使用旧的可执行文件。任何尝试打开该文件的新进程都将获得新的可执行文件。如果你在一个循环中有system("foo");
,每次执行时它都会看到名称为foo的文件当时代表的内容。
Windows处理文件的方式不同。通常,如果有一个进程在使用文件,则该文件会被锁定,不能被删除或替换。
这要看情况。
如果操作系统将整个可执行文件读入内存并不再引用磁盘镜像,则可以在“使用中”重新编译它。
但实际上,这种情况并不总是发生。如果操作系统保持对可执行文件的文件句柄打开状态(例如Windows),则会阻止文件被删除和/或覆盖。
在Linux / Unix中,可以覆盖“正在使用”的文件。有关详细说明,请参见David Thornley的答案。
我想它不会让你替换文件,因为在使用过程中Windows已将其锁定。
这要看情况而定。根据我的经验,在Linux上,如果你删除了一个程序(且它不太大),你仍然可以运行它。但我认为这并不是明确定义的行为。
至于循环,取决于你如何调用可执行文件,当它尝试执行一个只写了一半的程序时,你很可能会导致脚本崩溃。
可执行文件可能会在启动时完全加载到内存中,但如果它足够大并且运行时间足够长,操作系统可能会决定交换掉一些未使用的部分。
由于操作系统假设程序文件仍然存在,因此实际上没有必要将这些内存块写入交换文件。因此,它们被简单地无效化并重用。如果程序再次需要这些页面,则操作系统从可执行文件中加载它们。
在Windows中,这实际上是自动完成的,因为已加载的模块是内存映射文件。这也意味着在执行期间文件被锁定,您将无法轻松地覆盖它。
不确定Linux是否也是以同样的方式进行交换。