system 和 exec 的区别

2024-06-09 21:12
文章标签 区别 system exec

本文主要是介绍system 和 exec 的区别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在 linux 中,使用 system 和 exec 都可以执行一个程序或者执行一个命令。两者的区别如下:

system 中创建了一个子进程,在子进程中执行用户的命令,子进程执行完毕之后,system 会返回。exec 不会创建子进程,而是直接用 exec 要执行的进程来代替当前的进程,并且如果在执行过程中没有出现错误,那么 exec 是不会返回的,调用 exec 的进程永远也回不来了。

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 来执行 hello,hello 得到执行。

#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 不再打印

(2)exec 执行的程序 hello,打印 3 次 hello 之后退出,这个时候 exec 也不会返回了,after right exec 没有打印

(3)当 exec 找不到可执行文件时,会返回错误,并且设置了 errno,信息是 No such file or directory

2 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;
}

执行结果如下,从执行结果可以看出来:

(1)system 执行的时候只是阻塞当前这个线程的执行,并没有阻塞整个进程的执行, 在 system 执行的时候,main 函数中创建的 thread 还在运行,in thread 还在打印

(2)system 执行完毕之后,会返回,代码中的 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 创建了子进程。

这篇关于system 和 exec 的区别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1046313

相关文章

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

java中不同版本JSONObject区别小结

《java中不同版本JSONObject区别小结》本文主要介绍了java中不同版本JSONObject区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录1. FastjsON2. Jackson3. Gson4. org.json6. 总结在Jav

Oracle数据库如何切换登录用户(system和sys)

《Oracle数据库如何切换登录用户(system和sys)》文章介绍了如何使用SQL*Plus工具登录Oracle数据库的system用户,包括打开登录入口、输入用户名和口令、以及切换到sys用户的... 目录打开登录入口登录system用户总结打开登录入口win+R打开运行对话框,输php入:sqlp

数据库使用之union、union all、各种join的用法区别解析

《数据库使用之union、unionall、各种join的用法区别解析》:本文主要介绍SQL中的Union和UnionAll的区别,包括去重与否以及使用时的注意事项,还详细解释了Join关键字,... 目录一、Union 和Union All1、区别:2、注意点:3、具体举例二、Join关键字的区别&php

java中的HashSet与 == 和 equals的区别示例解析

《java中的HashSet与==和equals的区别示例解析》HashSet是Java中基于哈希表实现的集合类,特点包括:元素唯一、无序和可包含null,本文给大家介绍java中的HashSe... 目录什么是HashSetHashSet 的主要特点是HashSet 的常用方法hasSet存储为啥是无序的

2.1/5.1和7.1声道系统有什么区别? 音频声道的专业知识科普

《2.1/5.1和7.1声道系统有什么区别?音频声道的专业知识科普》当设置环绕声系统时,会遇到2.1、5.1、7.1、7.1.2、9.1等数字,当一遍又一遍地看到它们时,可能想知道它们是什... 想要把智能电视自带的音响升级成专业级的家庭影院系统吗?那么你将面临一个重要的选择——使用 2.1、5.1 还是

Python中@classmethod和@staticmethod的区别

《Python中@classmethod和@staticmethod的区别》本文主要介绍了Python中@classmethod和@staticmethod的区别,文中通过示例代码介绍的非常详细,对大... 目录1.@classmethod2.@staticmethod3.例子1.@classmethod

Golan中 new() 、 make() 和简短声明符的区别和使用

《Golan中new()、make()和简短声明符的区别和使用》Go语言中的new()、make()和简短声明符的区别和使用,new()用于分配内存并返回指针,make()用于初始化切片、映射... 详细介绍golang的new() 、 make() 和简短声明符的区别和使用。文章目录 `new()`

Python中json文件和jsonl文件的区别小结

《Python中json文件和jsonl文件的区别小结》本文主要介绍了JSON和JSONL两种文件格式的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下... 众所周知,jsON 文件是使用php JSON(JavaScripythonpt Object No

结构体和联合体的区别及说明

《结构体和联合体的区别及说明》文章主要介绍了C语言中的结构体和联合体,结构体是一种自定义的复合数据类型,可以包含多个成员,每个成员可以是不同的数据类型,联合体是一种特殊的数据结构,可以在内存中共享同一... 目录结构体和联合体的区别1. 结构体(Struct)2. 联合体(Union)3. 联合体与结构体的