system函数实践1:system函数进程的爸爸是谁?
创始人
2024-02-22 03:58:11

前言

有两个问题:

system函数中修改了环境变量,会不会影响执行它的进程?

       不会。

        首先,这个我测过了,因为我原本想用它来传递参数。

        为什么?因为system函数执行的时候,会先创建一个shell,然后再这个shell中执行命令,在一个正在shell中修改环境变量,会影响另一个正在运行的shell的环境变量吗?不会。

system函数执行命令实际上是创建一个进程,那么他的父进程是谁?

这个要分两种情况来考虑。下面使用实例解答。

一 简介

#include 
int system(const char *command);

函数描述: 

DESCRIPTION
       The system() library function uses fork(2) to create a child process that executes the shell command specified in command using execl(3) as follows:

           execl("/bin/sh", "sh", "-c", command, (char *) 0);

       system() returns after the command has been completed.

       During  execution of the command, SIGCHLD will be blocked, and SIGINT and SIGQUIT will be ignored, in the process that calls system() (these signals will be handled according to their defaults inside the child
       process that executes command).

       If command is NULL, then system() returns a status indicating whether a shell is available on the system

返回值:

 RETURN VALUE
       The return value of system() is one of the following:

       *  If command is NULL, then a nonzero value if a shell is available, or 0 if no shell is available.

       *  If a child process could not be created, or its status could not be retrieved, the return value is -1.

       *  If a shell could not be executed in the child process, then the return value is as though the child shell terminated by calling _exit(2) with the status 127.

       *  If all system calls succeed, then the return value is the termination status of the child shell used to execute command.  (The termination status of a shell is the termination status of the last command  it executes.)

       In the last two cases, the return value is a "wait status" that can be examined using the macros described in waitpid(2).  (i.e., WIFEXITED() WEXITSTATUS() and so on).

       system() does not affect the wait status of any other children.

二 实践 :

实践1:让system函数进程成为systemd的子进程

#include 
#include 
#include 
#include int main(int argc,char *argv[])
{printf("pid=%d\n",getpid());system("sleep 100&");printf("ok\n");sleep(100);return 0;
}

测试:在后台执行a.out,进程号是64064,进程树导出到ps.txt文件

csdn@ubuntu:~$ ./a.out &
[1] 64064
csdn@ubuntu:~$ pid=64064
okcsdn@ubuntu:~$ pstree -p > ps.txt
csdn@ubuntu:~$

 将进程树精简一下:如下所示system("sleep 100&");的进程号是64066,为什么不是64065,因为system函数的执行过程是,创建一个shell,然后再这个新shell中执行sleep。

未解?   

    这中间都发生了什么?它为什么会在a..out活着的时候,变成了别人的儿子?是道德的沦丧还是人性的扭曲?亦或是妈妈的改嫁?它为什么不是systemd的孙子?

        有一种相对较合理的解释,那就是sleep是在后台执行的。它的附近是sh,sh执行它时,sleep是后台执行,所示sh无需等他结束,sh自己结束了,但是sleep的父进程是sh,sleep没有父进程了,linux是不允许没有父进程的子进程的。所以sleep被systemd接管了。所以sleep变成了systemd的子进程。

csdn@ubuntu:~$ grep -A2 -E "grep|systemd|sleep|a.out" ps.txt
systemd(1)-+-NetworkManager(949)-+-dnsmasq(1117)|                     |-{gdbus}(1014)|                     `-{gmain}(1006)
--|-sleep(64066)|-smbd(1183)-+-smbd(1185)|            `-smbd(1193)
--|            `-sshd(60610)---sshd(60639)---bash(60640)---su(62226)---bash(62227)-+-a.out(64064)|                                                                                `-pstree(64074)|-systemd(2415)---(sd-pam)(2416)|-systemd-journal(385)|-systemd-logind(967)|-systemd-timesyn(671)---{sd-resolve}(684)|-systemd-udevd(411)|-udisksd(2841)-+-{cleanup}(2846)|               |-{gdbus}(2844)
csdn@ubuntu:~$

重新执行a.out&,然后使用 ps -l,这可以直接看到父进程的ID:如下所示,sleep进程的父进程ID是1。就是systemd。

csdn@ubuntu:~$ ps -l
F S   UID    PID   PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S  1004  62227  62226  0  80   0 -  6232 wait   pts/20   00:00:00 bash
0 S  1004  64102  62227  0  80   0 -  1088 hrtime pts/20   00:00:00 a.out
0 S  1004  64104      1  0  80   0 -  2257 hrtime pts/20   00:00:00 sleep
0 R  1004  64105  62227  0  80   0 -  7664 -      pts/20   00:00:00 ps
csdn@ubuntu:~$

实践 2:让system函数进程成为执行者的孙子进程

就是将system函数参数字符串后面的&去掉,修改前面的代码:

 //system("sleep 100&");system("sleep 100");

然后重新编译:运行,测试进程的PID是64129,sleep的父进程是sh,sh的父进程是a.out。

csdn@ubuntu:~$ ./a.out &
[1] 64129
csdn@ubuntu:~$ pid=64129csdn@ubuntu:~$ ps -l
F S   UID    PID   PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S  1004  62227  62226  0  80   0 -  6232 wait   pts/20   00:00:00 bash
0 S  1004  64129  62227  0  80   0 -  1088 wait   pts/20   00:00:00 a.out
0 S  1004  64130  64129  0  80   0 -  1126 wait   pts/20   00:00:00 sh
0 S  1004  64131  64130  0  80   0 -  2257 hrtime pts/20   00:00:00 sleep
0 R  1004  64132  62227  0  80   0 -  7664 -      pts/20   00:00:00 ps
csdn@ubuntu:~$

查看进程树:


csdn@ubuntu:~$ pstree -p > ps.txt
csdn@ubuntu:~$
systemd(1)-+-NetworkManager(949)-+-dnsmasq(1117)|                     |-{gdbus}(1014)|                     `-{gmain}(1006)
--|            `-sshd(60610)---sshd(60639)---bash(60640)---su(62226)---bash(62227)-+-a.out(64129)---sh(64130)---sleep(6413+|                                                                                `-pstree(64140)|-systemd(2415)---(sd-pam)(2416)|-systemd-journal(385)|-systemd-logind(967)|-systemd-timesyn(671)---{sd-resolve}(684)|-systemd-udevd(411)|-udisksd(2841)-+-{cleanup}(2846)|               |-{gdbus}(2844)
csdn@ubuntu:~$

进程树截图。 

 小结

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...