getpid

在内存中的每个进程都有一个属于自己的PID,我们可以通过ps ajx指令查看进程的基本属性从而查看一个进程的pid,那么这里我们就可以创建一个文件然后往里面写入一个死循环的代码,再创建一个makefile文件在里面实现一些基本的功能,那么这里的操作就如下:

输入make指令并执行新生成的可执行程序就会出现下面的现象:

这时屏幕上就开始不停的打印内容说明我们的进程真正不停的被执行所以这时就可以通过指令ps ajx 查看进程对应的属性:

但是这里显示的进程特别的多,而我们只想查看一个名为myproc的进程,所以这时就可以使用grep指令和管道来查找这里打印出来的内容,这里的指令为:ps ajx| grep 'myproc'

但是这样的查找有一个缺点就是没有显示头部的属性信息,我们无法知道这里的数据代表的是什么意思,所以这里就得将指令改成这样:ps ajx| head -1 && ps ajx|grep 'myproc'


这样显示进程的时候就会将进程的头部信息也显示出来,仔细地观察一下就可以看到myproc进程的pid为26893,但是这样查看进程PID的方法就有点麻烦,所以操作系统就提供了getpid函数这个函数可以直接返回本进程的PID0值(也可以把这里的本进程称之为子进程),并且这个函数没有任何的参数,我们来看看这个函数的介绍:

有了这个函数就可以对之前的文件进行修改,在文件里面调用这个函数并打印这个函数的返回值来显示一个进程的pid,那么修改后的代码如下:

  1 #include<stdio.h>2 #include<sys/types.h>3 #include<unistd.h>4 int main()5 {6     while(1)7     {8         printf("我是一个进程!我的pid为:%d\n",getpid());9         sleep(1);10     }11     return 0;12 }

重新输入make指令再运行一下可执行程序就会出现下面的现象:

并且跟指令ps ajx| head -1 && ps ajx|grep 'myproc'显示的值是一样的

那么这就是getpid函数的作用。

getppid

getpid的作用是获取子进程的id这个我们都可以理解,当不停的把程序加载进内存的时候子进程的id会不停的发生变化比如说下面的操作:

而getppid的作用就是获取子进程的父进程的id,我们来看看这个函数的介绍:

这个函数没有参数并且该函数的返回值就是父进程的id,所以通过这个函数我们就可以在程序里面获取该进程的父进程的id,那么修改后的代码就如下:

  1 #include<stdio.h>2 #include<sys/types.h>3 #include<unistd.h>4 int main()5 {6     printf("我是一个进程!我的pid为:%d 我的父进程为:%d",getpid(),getppid());                                                               7     return 0;8 }

然后不停的执行程序就可以看到下面的现象:

我们发现这里的执行结果就与上面的有一些不一样:子进程的id在不停的发生变化,但是该进程的父进程的id却一直没有发生改变此时父进程的id为32282那这是为什么呢?我们退出服务器重新登录再运行一下这个程序看看结果又是什么样的?

此时父进程的id发生了改变变成了8368,而且我们再创建一个文件

  1 #include<stdio.h>2 #include<unistd.h>3 #include<sys/types.h>4 int main()5 {6     printf("我是另外一个进程我的id为:%d 我的父进程为:%d",getpid(),getppid());7 }

并生成可执行程序打印这个进程的父进程id时我们依然会发现这个id是8368

那这是为什么呢?这个8368到底是谁啊?那么为了解决这个问题我们可以通过指令
ps ajx| head -1 && ps ajx|grep 8368来查找一下这个id对应的进程的名字是什么?那么这里的查找结果如下

这个PID对应的进程叫做bash。之前我给大家讲过一个故事说张三特别喜欢如花但是张三的情商特别的低不善于和女生沟通所以张三就找当地一个特别著名的媒婆:王婆,王婆受到了张三的请求跑去找了如花可是如花一个跟别人与子偕手白头到老了,所以王婆也没有办法完成张三的请求可是张三这个人脑子一根筋他非如花不娶而且他的爸爸是村长,他就用着他爸爸的权力强迫王婆完成她的请求,王婆一看这有点进退两难啊,所以王婆就不停的招聘实习生让实习生去跟如花说好话,一旦这个实习生没有完成任务或者放弃任务了王婆就将这个实习生炒鱿鱼并招聘其他的实习生来继续完成这个任务,实习生有没有崩溃实习生有没有完成任务都和王婆本人没有任何的关系,这样王婆既不用与如花直接接触又可以逃避村长和张三的强迫,那么这里的王婆就是bash这里的实习生就是我们在命令行上面执行的各种可执行程序,可执行程序是否运行成功可执行程序是否存在问题都不会影响到bash的稳定,因为这里的程序是以子进程的方式执行,子进程的父进程是bash也就是命令行,我们可以使用kill -9指令来杀死父进程看看有什么什么反应:

我们可以看到当杀死了父进程bash之后就直接断开了连接让我们重新登录,而再次登录的时候就会发现父进程的pid又发生了变化,也就是说我们每次登录机器的时候操作系统都会给我们分配一个新的shell或者说是bash再或者说是命令行,而命令行上启动的进程,一般它的父进程没有特殊情况的话都是bash。

那么这就是父进程希望大家能够理解

fork

我们上面解释了什么是子进程什么是父进程,而fork函数的功能就是在父进程中创建子进程,我们来看看fork函数的介绍:


啊这里的内容就非常的多大家就只用知道几点就行,首先这个fork函数是没有参数的并且该函数有个返回值,学习这个函数的第一步就是如何证明fork函数创建了子进程,我们来看看下面的代码:

1 #include<stdio.h>2 #include<sys/types.h>3 #include<unistd.h>4 int main()5 {6     printf("我是一个进程!我的pid为:%d 我的父进程为:%d\n",getpid(),getppid());7     return 0;8 }

将其运行一下就可以看到屏幕上只打印了一行语句:

但是此时我们将程序进行修改在打印语句前面调用一次frok函数看看结果会变成什么样:

  1 #include<stdio.h>2 #include<sys/types.h>3 #include<unistd.h>4 int main()5 {6     fork();7     printf("我是一个进程!我的pid为:%d 我的父进程为:%d\n",getpid(),getppid());8     return 0;                                                                                                                                9 }

再次运行一下程序就可以看到这里打印出来了两句话,并且这两句话的内容是不一样的

那这就能够说明我们这段程序在执行的过程中创建了一个子进程,并且在子进程中也执行了printf语句,可是这里就有个问题,该程序在创建子进程的时候是从代码一开始创建的就创建了子进程还是将fork函数运行完就创建了子进程的呢?所以为了解决这个问题就可以将文件中的代码进行修改在fork函数之前再添加一个printf函数,那么这里的代码如下:

  1 #include<stdio.h>2 #include<sys/types.h>3 #include<unistd.h>4 int main()5 {6     printf("hello world\n");7     fork();8     printf("我是一个进程!我的pid为:%d 我的父进程为:%d\n",getpid(),getppid());9     return 0;10 }

如果hello world被打印了一次就说明父进程是在调用fork函数的时候创建的子进程,如果hello world被打印了两次就说明子程序的创建应该是在父进程刚开始被执行的时候,那么上述代码执行的结果就如下:

这就说明子进程的创建是在调用fork函数的时候,并且当fork函数创建子进程之后会有两个进程来执行fork函数之后的代码所以这里就会打印两次我是一个进程。看了上面的函数介绍我们可以知道一件事就是fork函数会有一个返回值,而且父进程的返回值和子进程的返回值是不一样的,父进程会把子进程的id作为fork函数的返回值,而子进程会把0作为父进程的返回值,比如说下面的代码:

  1 #include<stdio.h>2 #include<sys/types.h>3 #include<unistd.h>4 int main()5 {6     int i=fork();                                                                                                                            7     printf("fork函数的返回值为%d\n",i);8     return 0;9 }

这段代码的执行结果为

我们可以看到这里打印了两个数据其中一个为0,那么这个0就是子进程fork函数的返回值,非0就是父进程的fork函数的返回值,这就是fork函数的特性,该函数虽然只调用了一次但是却有两个返回值,子进程的fork永远都返回0父进程的fork永远都返回子进程的pid,所以我们就可以根据父子进程的fork函数的返回值来让父子进程执行接下来的不同的代码比如说下面的代码:

  1 #include<stdio.h>2 #include<sys/types.h>3 #include<unistd.h>4 int main()5 {6     int i=fork();7     int a=10;8     int b=20;9     if(i!=0)10     {11         printf("我是父进程\n");12         printf("a+b的结果为:%d\n",a+b);13     }14     else15     {16         printf("我是子进程\n");17         printf("b-a的结果为:%d\n",b-a);                                                                                                     18     }19 20     return 0;21 }

这段代码的运行结果如下:

我们可以看到这里虽然创建了一个子进程但是子进程和父进程却在各自的程序中根据fork函数的返回值执行者不同的代码,那么这就是fork函数的返回值的意义希望大家能够理解。

linux入门---三个操作系统调用接口相关推荐

  1. 【README】Linux系统编程必读:本专栏内容提要以及系统调用接口总结

    文章目录 前言 第一部分:博客知识点 (1)基础篇 Linux系统编程1:Linux中使用率最高的一些命令 Linux系统编程2:详解Linux中的权限问题 Linux系统编程3:基础篇之详解Linu ...

  2. 【Linux 内核 内存管理】内存管理架构 ① ( 内存管理架构组成 | 用户空间 | 内核空间 | MMU 硬件 | Linux 内核架构层次 | Linux 系统调用接口 )

    文章目录 一.内存管理架构组成 ( 用户空间 | 内核空间 | MMU 硬件 ) 二.Linux 内核架构层次 三.Linux 系统调用接口 一.内存管理架构组成 ( 用户空间 | 内核空间 | MM ...

  3. 【Linux入门连载三】Linux常用的基本命令

    参考:狂神说Linux02:常用的基本命令(必掌握) 写在前面:如果读者没有Linux环境,可以像笔者这样使用虚拟机来学习Linux 的基本命令与操作.请移步笔者另一篇文章:[Win10下安装Linu ...

  4. linux ubuntu 桌面,Ubuntu Linux 入门(三):熟悉 Ubuntu Linux 桌面环境

    Posted on 2011/08/16, 13:53, by Terry Chen, under Linux. 在Ubuntu Linux 入门(二):安装 Ubuntu Linux一文中,我们已经 ...

  5. linux网络系统调用,Linux网络系统调用接口--待续

    [内核版本:linux-2.6.30] Linux网络系统调用接口其定义在:linux/net/socket.c 其中主要的接口,如下所示. 1. socket Function: Definitio ...

  6. python爬虫入门教程(三):淘女郎爬虫 ( 接口解析 | 图片下载 )

    2019/10/28更新 网站已改版,代码已失效(其实早就失效了,但我懒得改...)此博文仅供做思路上的参考 代码使用python2编写,因已失效,就未改写成python3 爬虫入门系列教程: pyt ...

  7. 嵌入式 Linux 入门 环境篇(三、开发板和 PC 的网络互通)

    嵌入式 Linux入门 环境篇第三课,开发板与PC的网络配置, 我们要实现 windows.ubuntu 和开发板三者的互通. ...... by 矜辰所致 前言 在环境篇前面的文章我们通过终端工具使 ...

  8. linux入门(三)常见Linux指令及其用法

    一.上回说到说到Linux的shell指令运行的原理,这回我们来看看Linux中shell的权限管理,所谓的"权限"是指某一类人做某一件事的权利. 在shell中这一类人被分为了三 ...

  9. 【Linux】Linux入门学习之常用命令三

    介绍 这里是小编成长之路的历程,也是小编的学习之路.希望和各位大佬们一起成长! 以下为小编最喜欢的两句话: 要有最朴素的生活和最遥远的梦想,即使明天天寒地冻,山高水远,路远马亡. 一个人为什么要努力? ...

最新文章

  1. 请收下这份NLP热门词汇解读
  2. Tomcat部署Maven的JavaWeb项目——这样我们写完程序把程序打包为war包,拿到用户那边启动服务器就可以运行了,简单轻松
  3. 计算机专业配置笔记本,学计算机专业的买什么样配置和价格的笔记本好?
  4. hdoj 1004 学习思路
  5. (23)Verilog HDL条件语句:if-else语句
  6. 灰度拉伸python_灰度变换之灰度线性拉伸(算法1)
  7. OpenStack点滴01-概览
  8. html文本框%3cdiv%3e,index.html
  9. docker 部署Java项目
  10. 人工智能的未来是否真的会成为工人的乌托邦?
  11. java 32位_java8update下载
  12. 计算机服务怎么打开flash,快速讲解Win10自带的浏览器如何开启Adobe Flash?
  13. 【Python - OpenCV】数字图像项目实战(四) - 位姿估计
  14. 公器私用--大互联网自建云分析
  15. qq屏蔽怎么知道对方信息(qq屏蔽怎么让对方知道)
  16. 算法---斐波那契思想
  17. AUTO_INCREMENT
  18. linux权限验证,squash相关权限验证
  19. 锂电池充电过程及电路设计
  20. 姑苏寻古[小刚执笔]

热门文章

  1. (附源码)springboot教学评价 毕业设计 641310
  2. Spring MVC【钢镚核恒】
  3. 对比苹果表,说说moto360
  4. c语言数组长度可以在键盘上输入吗,C语言编程(用指针) 定义一个数组长度为10,从键盘输入数组,将每一个元素除以2后,输出数组...
  5. 力扣:安排电影院座位
  6. vex机器人 亚洲公开赛_VEX机器人亚洲公开赛工程笔记大公开:华硕商用赋能青少年科学梦想...
  7. 《画解数据结构》「归并排序」算法教程
  8. SQL:使用DATE_ADD函数加减时间
  9. LSC问题(不连续问题)
  10. STM32实战项目-触摸按键