system 和 exec 的区别

发布时间:2026/7/27 19:25:49

system 和 exec 的区别 在 linux 中使用 system 和 exec 都可以执行一个程序或者执行一个命令。两者的区别如下system 中创建了一个子进程在子进程中执行用户的命令子进程执行完毕之后system 会返回。exec 不会创建子进程而是直接用 exec 要执行的进程来代替当前的进程并且如果在执行过程中没有出现错误那么 exec 是不会返回的调用 exec 的进程永远也回不来了。所以如果不想让exec代替当前进程那么需要先fork之后再在子进程中执行execfork返回值为0的分支是子进程。1 exec使用如下两个代码来演示 exec 的执行过程。如下代码使用 gcc hello.c -o hello 来编译出可执行文件 hello。这段代码中每隔一秒中打印一次 hello打印 3 次之后退出。#include stdlib.h #include stdio.h #include string.h #include unistd.h int main() { int i 0; while (i 3) { printf(hello\n); sleep(1); i; } return 0; }下边的代码中main 函数中首先创建了一个线程线程中每隔 1 秒打印一次 in thread。打印 5 次之后调用 execv 来执行一个程序第一次执行的程序是 hello1是一个不存在的可执行文件这种情况下 execv 会返回错误。第二次调用 execv 来执行 hellohello 得到执行。#include iostream #include thread #include unistd.h void thread_func() { while (1) { std::cout in thread\n; sleep(1); } } int main() { std::thread t(thread_func); sleep(5); std::cout before wrong exec\n; int ret execv(./hello1, NULL); if (ret 0) { perror(exec error:); } std::cout after wrong exec\n; std::cout before right exec\n; execv(./hello, NULL); std::cout after right exec\n; return 0; }程序运行结果如下从打印信息来看可以得出如下 3 点1调用 exec 正确执行的时候exec 执行的可执行文件覆盖了整个程序的镜像不仅仅是 main 函数所在的主线程不执行了main 函数中创建的子线程也不运行了调用 exec 之后 in thread 不再打印2exec 执行的程序 hello打印 3 次 hello 之后退出这个时候 exec 也不会返回了after right exec 没有打印3当 exec 找不到可执行文件时会返回错误并且设置了 errno信息是 No such file or directory2 system将 execv 替换程 system代码如下。#include iostream #include thread #include unistd.h void thread_func() { while (1) { std::cout in thread\n; sleep(1); } } int main() { std::thread t(thread_func); t.detach(); sleep(5); std::cout before wrong system\n; int ret system(./hello1); if (ret 0) { perror(1 system error:); } std::cout after wrong system\n; std::cout before right system\n; ret system(./hello); if (ret 0) { perror(2 system error:); } std::cout after right system\n; return 0; }执行结果如下从执行结果可以看出来1system 执行的时候只是阻塞当前这个线程的执行并没有阻塞整个进程的执行 在 system 执行的时候main 函数中创建的 thread 还在运行in thread 还在打印2system 执行完毕之后会返回代码中的 after right system 打印了出来3 popen在软件开发中有的时候有这样一个需求就是在代码中执行一个命令并且在代码中还可以获取到执行这个命令时的打印信息。比如在控制台我们可以很容易的执行 free 命令来查看系统内存使用情况如果我们想在代码中执行 free 命令并且获取 free 命令的显示信息最后把 free 显示的信息打印出来应该怎么实现呢 可以通过 popen 来实现。如下代码可以实现上述功能。popen 结合 fgets 可以获取到命令执行的打印信息使用完毕之后要通过 pclose关闭句柄。#include stdio.h #include stdlib.h #include unistd.h int main() { FILE *fp; char buffer[1024]; sleep(2); fp popen(free, r); if (fp NULL) { printf(Error: Failed to run command\n); return EXIT_FAILURE; } while (fgets(buffer, sizeof(buffer), fp) ! NULL) { printf(result:\n); printf(%s, buffer); } pclose(fp); return EXIT_SUCCESS; }为了使用 strace 来追踪 popen 相关的系统调用在调用 popen 之前睡了 2s。通过如下截图可以看到popen 的时候使用了管道也通过 vfork 创建了子进程。

相关新闻