popen和system函数的区别 以及 popen打开的FILE指针能否用close替代fclose关闭

42 篇文章 2 订阅
订阅专栏
34 篇文章 1 订阅
订阅专栏

popen和system函数的区别

在c/cpp程序中执行shell命令,通常有两种方式,一种是使用popen函数,一种是使用system函数;两者会调用fork函数从父进程中fork出一个子进程,然后在子进程中执行shell命令,其主要的区别如下:

  • popen
    popen会先fork一个子进程,然后子进程去执行shell命令,函数同时返回一个FILE指针给调用者,调用者可以根据FILE指针来获取函数的执行结果。popen是非阻塞的,即执行后可立即返回。
  • system
    system会fork一个子进程,然后父进程等待子进程结束,也就是执行system函数是阻塞的,如果调用 system("sleep 1"),将会延迟1s再执行system后面的代码。

popen打开的FILE句柄能否用close替代fclose关闭?

急的话直接看答案就行:不行,会有一些副作用

实际中遇到的问题

最近遇到一个这样的问题:
场景:为了完成相关功能,需要在程序调用shell命令,用到了popen;为了支持多个命令并发,
在获取shell命令的结果时使用reactor模式(借助了epoll的多路复用能力,epoll监听对应的fd是否有事件过来),以提升处理效率。其伪代码大概如下:

//注册信号处理函数,防止产生僵死进程
signal(SIGCHLD, SIG_IGN);
//将popen打开的文件描述符加入epoll
FILE * file = popen("shell cmd", "r"); //这边shell cmd为具体的shell脚本
//将FILE转int,然后加入到epoll中
int fd = fileno(file);
//将描述符设置为非阻塞模式
set_no_block(fd);
struct epoll_event event;
event.events = EPOLLIN | EPOLL UT;
event.data = ...; //epoll保存的data
epoll_ctl(epfd, EPOLL_CTL_ADD, fd,&event);

在epoll主循环中,

int num = epoll_wait(timeout);
for(int i = 0; i < num; i++)
{
	//处理epoll事件
	processEvent(...)
}

其中processEvent的大体逻辑如下:

void processEvent(struct epoll_event* event)
{
	//事件处理,比如读取结果等

    //收尾工作,如删除epoll监听的fd,关闭文件描述符
    ...
    close(fd); //这边fd为第一部分添加尽量的描述符fd,可以从event中获取
}

功能开发完成后,自测ok,然后就放着让他跑,看看稳定性。这时程序的cpu使用率有时会飙升,外部程序调用该服务存在间断性的失败。这时用top或者ps看一下进程,会发现有时候出现多个此进程的子进程;且从失败的时间点看,周期和popen执行的周期基本能对上。由于子进程是fork出来的,popen内部调用了fork,就怀疑是popen带来的问题。
排查程序发现可能是使用close替代pclose来关闭用popen打开的描述符导致的问题,然后改了下代码后,发现该问题消失。

demo测试分析

为了对比使用close和fclose关闭popen打开的描述符的差别,这边进行了下面的实验,测试代码如下:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <iostream>
using namespace std;

int main()
{
        signal(SIGCHLD, SIG_IGN);
        while(1)
        {
        char szCommand[128] = {0};
        snprintf(szCommand, sizeof(szCommand) - 1, "cat testfile"); //这边testfile为一个文本文件
        FILE* fp = popen(szCommand, "r");
        if(NULL == fp)
        {
                std::cout << "popen failed" << endl;
        }
        usleep(1000);
        
        //1
        int fd = fileno(fp);
        close(fd);
        
        //2
        //fclose(fp);
        }
        return 0;

}

分别使用close和fclose,编译出两个testpopen文件,然后运行,过一阵后,使用close关闭的程序表现如下:
使用close关闭的效果

使用pclose关闭的效果如下:
使用pclose关闭的效果
通过对比,看出了差异,如果通过close来关闭popen打开的FILE描述符的话,有些负面的作用【cpu高了,且有部分内存泄露】。

查了下pclose和close的差异,pclose除了会关闭文件描述符之外,还具有pclose会调用waitpid为popen时fork的子进程收尸,而fclose不会;另外pclose还具有在关闭文件时冲刷缓冲区的功能。

重新实现popen和system函数
05-27
在编程领域,`popen` 和 `system` 函数是C/C++标准库中用于执行命令行进程的工具。它们提供了方便的方式来与操作系统交互,执行外部程序并读取或写入其输出。然而,有时出于安全或性能考虑,开发者可能需要自定义...
popen和system区别
YUAN1125的专栏
02-26 2557
popen和system都可以执行外部命令。 popen相当于是先创建一个管道,fork,关闭管道的一端,执行exec,返回一个标准的io文件指针。 system相当于是先后调用了fork, exec,waitpid来执行外部命令 popen本身是不阻塞的,要通过标准io的读取使它阻塞 system本身就是阻塞的。   最近写的程序,要求进程在调用的外部命令运行完毕
Linux的system和popen的差异
轮子工厂
07-30 1748
1. system()和popen()简介 在linux中我们可以通过system()来执行一个shell命令,popen()也是执行shell命令并且通过管道和shell命令进行通信。 system()、popen()给我们处理了fork、exec、waitpid等一系列的处理流程,让我们只需要关注最后的返回结果(函数的返回值)即可。 2. system()、popen()源码 首先我们来看一下这两个函数在源码(伪代码)上面的差异。 int system(const char *command
popen和system的区别
蓬莱道人的博客
12-12 4054
1、system() 串行执行,程序会阻塞到system执行完成。 2、popen() 并行执行,可以在程序中读取命令的标准输出,也可在程序中写入命令的标准输入。
Linux系统编程之进程(system函数popen函数
最新发布
咖喱年糕的博客
10-18 3075
system() 函数是一个C标准库函数,用于执行系统命令或外部程序。它允许你从C程序中调用命令行命令。NAMEcommand 是一个以空终止的C字符串,包含要执行的命令。system() 函数的工作方式如下:它启动一个新的shell进程(通常是默认的命令行shell)。然后在新的shell中执行command字符串中指定的命令。当命令执行完毕后,system() 函数等待命令的返回状态(退出状态)。最后,它返回命令的返回状态。// 在Unix/Linux系统上列出当前目录的文件。
fork、exec系列与system、popen区别.rar_UNIX popen_linux system pop_pop
09-21
在UNIX和Linux操作系统中,进程创建和控制是通过一系列系统调用来实现的,其中最常见的是`fork`、`exec`系列以及`system`和`popen`函数。这些调用各自有不同的特性和用途,理解它们的区别对于进行系统级编程至关重要...
Linux中popen函数的作用小结
01-20
简单说一下popen()函数 函数定义 #include FILE * popen(const char *command , const char *type ); int pclose(FILE *stream);...如果shell不能被执行,则pclose()返回的终止状态与shell已执行e
linux中 popen 和 system 区别和联系
布袋和尚
06-21 688
(SAW:Game Over!)
Linux-popen,system函数差异
mxrrr_sunshine的博客
03-22 615
popen在linux下,不懂得可以查看帮助手册,我们先看看man手册怎么说。 可以看到,手册给出了两个函数原型,popen与pclose,其实我们很容易就能联想到另外一组函数,fopen,fclose。这两个函数是用来打开关闭文件的。所以其实我们已经可以猜到popen,pclose这两个函数的作用是什么了,p在linux下我们见到的地方大多数都与“管道”与关,所以可想而知,这两个函数实现的功
linux popen()与system()的区别
weixin_33695450的博客
01-25 525
linux popen()与system()的区别 popen() 可以在调用程序和POSIX shell /usr/bin/sh 要执行的命令之间创建一个管道(请参阅sh-posix(1) )。 popen() 的参数是指向以空字符结尾的字符串的指针,这些字符串分别包含一个shell 命令行和一个I/O 模式,此 模式可以是进行读取的r ,或进行写入的w 。 popen() 可返回一个流指针,...
system与popen对比
tyro_wzp的博客
03-06 543
popen相当于是先创建一个管道,fork,关闭管道的一端,执行exec,返回一个标准的io文件指针。system相当于是先后调用了fork, exec,wait来执行外部命令。2.用popen执行输入hello word到文件中。1.创建文件,写入hello word。2.用system执行cat文件。2.用popen执行cat文件。popen和system都可以执行外部命令。1.创建文件,写入hello word。
对于linux下system()函数的深度理解(整理)
未冬生
07-16 1267
这几天调程序(嵌入式linux),发现程序有时就莫名其妙的死掉,每次都定位在程序中不同的system()函数,直接在shell下输入system()函数中调用的命令也都一切正常.就没理这个bug,以为是其他的代码影响到这个,或是内核驱动文件系统什么的异常导致,昨天有出现了这个问题,就随手百了一下度,问题出现了,很多人都说system()函数要慎用要少用要能不用则不用,system()函数
popen 与system函数笔记
chenpuo的博客
09-10 1083
文章大部分为摘抄,有些没有标明出处,请谅解。 通过popen查看selinux是否打开: #include #include int main () { char cmd[64] = {0}; char buf[64] = {0}; FILE *fd; sprintf(cmd,"getenforce\n"); fd = popen(cmd, "r"
为什么使用popen函数代替system
嵌入式Linux开发从业者,立志做一名优秀的博客输出者!
12-13 477
popen 函数与system函数评估比较
Linux 中 popen 函数与 system 函数区别
胡小哲的博客
03-04 903
popen 函数 函数原型 #include &lt;stdio.h&gt; FILE *popen(const char *command, const char *type); command : 一个指向以 NULL 结尾的 shell 命令字符串的指针。这个字符串会使用 -c 标志传到 bin/sh ,shell 将执行这个命令。 type : 指向以 NULL ...
popen函数和system函数详解
热门推荐
everthing willl be ok
03-27 3万+
1、popen函数 我们先用man指令查一下popen函数函数说明: (1)popen()会调用fork()产生子进程,然后从子进程中调用/bin/sh -c来执行参数command的指令。 (2)参数type可使用“r”代表读取,“w”代表写入。依照此type值,popen()会建立管道连到子进程的标准输出设备或标准输入设备,然后返回一个文件指针。随后进程便可利用此文件指针来读取...
popen函数和system函数区别
05-23
`popen` 和 `system` 都是 C 语言中用于执行外部命令的函数区别如下: 1. 用途不同:`system` 函数主要用于执行外部命令,而 `popen` 函数主要用于执行外部命令并返回其输出结果。 2. 返回值不同:`system` 函数的返回值是执行命令的状态码,而 `popen` 函数的返回值是一个文件指针,可以通过读取该文件指针来获取命令的输出结果。 3. 使用方式不同:`system` 函数只需要传入要执行的命令字符串即可,而 `popen` 函数需要传入要执行的命令字符串和一个模式(如 "r" 或 "w"),以确定是读取命令的输出还是向命令的输入写入数据。 4. 安全性不同:`system` 函数存在安全性问题,因为它可以执行任意命令。而 `popen` 函数相对更安全,因为它只能执行指定的命令,并且可以通过管道机制来避免命令注入和攻击。 因此,在需要执行外部命令并获取其输出结果时,建议使用 `popen` 函数,而在简单场景下可使用 `system` 函数。同时,为了防止命令注入等安全问题,应该尽可能避免使用 `system` 函数
写文章

热门文章

  • Makefile中获取当前执行的Makefile所在路径 26478
  • syslog-ng详解——syslog-ng配置语法 18487
  • vscode无法跳转到函数定义 15018
  • 彻底弄懂EPOLLOUT事件 9212
  • 如何修改jar包中的class文件 7054

分类专栏

  • 性能优化 12篇
  • 服务器运维 6篇
  • GO语言入门和进阶 3篇
  • 书籍 1篇
  • syslog-ng详解 6篇
  • C/C++ 42篇
  • 算法和数据结构 10篇
  • 网络编程 28篇
  • 设计模式 7篇
  • makefile+shell 17篇
  • 操作系统 34篇
  • 数据库 3篇
  • 进程通信 10篇
  • 程序调试相关 3篇
  • 其他 9篇
  • 工具软件 41篇
  • Android 6篇
  • java 5篇
  • STL 7篇
  • 构建管理 12篇
  • python 6篇
  • redis 2篇
  • uml 1篇
  • 多线程编程 3篇
  • 内核编程 10篇
  • WIN 1篇
  • 密码学 4篇
  • Wi-Fi 2篇
  • 软件问题汇总 1篇
  • memcache 2篇
  • 分布式 3篇
  • json 2篇

最新评论

  • vscode无法跳转到函数定义

    将若垂天之云: C/C++插件之前好像整理插件的时候不小心卸载了,很难想象自己居然被这么傻杯的问题困扰了2天。十分感谢答主

  • linux下core文件被系统转存而不能直接找到

    CSDN-Ada助手: CS入门 技能树或许可以帮到你:https://edu.csdn.net/skill/gml?utm_source=AI_act_gml

  • 分享些电子书,有需要的自行下载

    2401_83010091: 哥,打不开了,请问可以再分享一下这本书么?祝您2024新年快乐,万事胜意🌹 [格林斯潘回忆录.动荡年代].Alan.Greenspan.-.The.Age.of.Turbulence.pdf

  • vscode无法跳转到函数定义

    AtItAgain: 感谢,禁用再启用就好了

  • vscode无法跳转到函数定义

    ViodMian: 确实有用,点赞

最新文章

  • Vscode搜索报错“UniError, if an URI contains an authority component...“
  • linux下core文件被系统转存而不能直接找到
  • ASan runtime error
2024年3篇
2023年9篇
2022年6篇
2021年26篇
2020年30篇
2019年7篇
2018年27篇
2017年59篇
2016年34篇
2015年32篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

玻璃钢生产厂家龙柱玻璃钢雕塑安装柱子玻璃钢雕塑玻璃钢镜面不锈钢雕塑定做价格玻璃钢玩偶卡通人物雕塑上海定制玻璃钢雕塑市场萍乡步行街玻璃钢雕塑制作芜湖欧式玻璃钢雕塑徐州校园玻璃钢雕塑安装开封室内玻璃钢卡通雕塑生产贵州楼盘玻璃钢动物雕塑小品制作户外玻璃钢雕塑生产厂家河南大型商场美陈价格玻璃钢雕塑可以上面加字吗中山玻璃钢卡通雕塑规格沧州动物玻璃钢雕塑价格玻璃钢卡通机器人雕塑郑州肖像玻璃钢人物雕塑制造瑞金玻璃钢雕塑厂家江苏常见商场美陈有哪些贵港玻璃钢雕塑制作息烽玻璃钢雕塑定做电话玻璃钢雕塑制作价位华龙玻璃钢雕塑费用南阳镇平公园玻璃钢雕塑重庆玻璃钢熊雕塑陕西楼盘玻璃钢卡通形象雕塑上海商场主题创意商业美陈步骤广东通道商场美陈玻璃钢艺术品雕塑专业公仔玻璃钢卡通雕塑手工制作香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化