[Linux系统编程]进程(二)

本文详细探讨了Linux系统编程中的进程相关概念,包括进程与程序的区别、并发执行、虚拟内存和虚拟地址空间、进程控制块PCB、进程状态转换。介绍了fork、getpid、getppid等函数在进程控制中的应用,以及孤儿进程和僵尸进程的概念。通过案例分析了进程共享、wait和waitpid函数的使用,帮助读者深入理解进程管理和控制。
摘要由CSDN通过智能技术生成

       距离上一次利用高并发技术实现360度行车记录仪功能已经过去半年了。开始写一系列关于系统编程和网络编程内容进行总结。
       温故而知新,欢迎大家讨论学习。

第一次复习时间2021-09-02
补充点: 虚拟地址空间的概念
僵尸进程和孤儿进程更为具体的描述

1 进程相关概念

    一些比较基本的概念,如果学过操作系统,这些内容都很常见,可以适当跳过…

  • 单道程序设计
  • 多道程序设计
  • 微观串行、宏观并行 时间片
  • 同步 和 异步
  • 并发和并行

相关术语参考链接(重)

1.1 程序和进程

    “程序(Program)”是一个静态的概念,一般对应于操作系统中的一个可执行文件
    执行中的程序叫做进程(Process),是一个动态的概念。现代的操作系统都可以同时启动多个进程。比如:我们在用酷狗听音乐,也可以使用eclipse写代码,也可以同时用浏览器查看网页。

1.2 并发

    并发是多个任务交替执行的,多个任务之间可能还是串行的。所有的并发处理都有排队等候,唤醒和执行这三个步骤。所以并发是宏观的观念,在微观上他们都是序列被处理的,只不过资源不会在某一个上被阻塞(一般是通过时间片轮转),所以在宏观上多个几乎同时到达的请求同时在被处理。如果是同一时刻到达的请求也会根据优先级的不同,先后进入队列排队等候执行。并发针对的是多个请求,比如:一个CPU,一个web服务,同时涌入多个请求,CPU需要交替切换的执行多个请求,而不是一个请求执行完成之后再执行下一个请求。并发的实质是一个物理CPU(也可以是多个物理CPU)在若干个程序之间多路复用,并发性是对有限物理资源强制行使 多用户共享以提高效率。

1.3 虚拟内存和虚拟地址空间

参考链接
    虚拟内存:虚拟内存是一种逻辑上扩充物理内存的技术。基本思想是用软、硬件技术把内存与外存这两级存储器当做一级存储器来用。虚拟内存技术的实现利用了自动覆盖和交换技术。简单的说就是将硬盘的一部分作为内存来使用

    虚拟地址空间:在32位的i386 CPU的地址总线的是32位的,也就是说可以寻找到4G的地址空间。我们的程序被CPU执行,就是0x000000000xFFFFFFFF这一段地址中。高1G的空间为内核空间,由操作系统调用,低3G的空间为用户空间,由用户使用。
    CPU在寻址的时候,是按照虚拟地址来寻址,然后通过MMU(内存管理单元)将虚拟地址转换为物理地址。因为只有程序的一部分加入到内存中,所以会出现所寻找的地址不在内存中的情况(CPU产生缺页异常),如果在内存不足的情况下,就会通过页面调度算法来将内存中的页面置换出来,然后将在外存中的页面加入到内存中,使程序继续正常运行。
原图链接
在这里插入图片描述

0902补充一个比较好的总结

为了在多进程环境下,使得进程之间的内存地址不受影响,相互隔离,于是操作系统就为每个进程独立分配一套虚拟地址空间,每个程序只关心自己的虚拟地址就可以,实际上大家的虚拟地址都是一样的,但分布到物理地址内存是不一样的。作为程序,也不用关心物理地址的事情。
 
每个进程都有自己的虚拟空间,而物理内存只有一个,所以当启用了大量的进程,物理内存必然会很紧张,于是操作系统会通过内存交换技术,把不常使用的内存暂时存放到硬盘(换出)(这个就是虚拟内存),在需要的时候再装载回物理内存(换入)。
 
那既然有了虚拟地址空间,那必然要把虚拟地址「映射」到物理地址,这个事情通常由操作系统来维护。
 
那么对于虚拟地址与物理地址的映射关系,可以有分段和分页的方式,同时两者结合都是可以的。
 
内存分段是根据程序的逻辑角度,分成了栈段、堆段、数据段、代码段等,这样可以分离出不同属性的段,同时是一块连续的空间。但是每个段的大小都不是统一的,这就会导致内存碎片和内存交换效率低的问题。
 
于是,就出现了内存分页,把虚拟空间和物理空间分成大小固定的页,如在 Linux 系统中,每一页的大小为 4KB。由于分了页后,就不会产生细小的内存碎片。同时在内存交换的时候,写入硬盘也就一个页或几个页,这就大大提高了内存交换的效率。
 
再来,为了解决简单分页产生的页表过大的问题,就有了多级页表,它解决了空间上的问题,但这就会导致 CPU 在寻址的过程中,需要有很多层表参与,加大了时间上的开销。于是根据程序的局部性原理,在 CPU 芯片中加入了 TLB,负责缓存最近常被访问的页表项,大大提高了地址的转换速度。
 
Linux 系统主要采用了分页管理,但是由于 Intel 处理器的发展史,Linux 系统无法避免分段管理。于是 Linux 就把所有段的基地址设为 0,也就意味着所有程序的地址空间都是线性地址空间(虚拟地址),相当于屏蔽了 CPU 逻辑地址的概念,所以段只被用于访问控制和内存保护。另外,Linxu 系统中虚拟空间分布可分为用户态和内核态两部分,其中用户态的分布:代码段、全局变量、BSS、函数栈、堆内存、映射区。

1.4 进程控制块PCB

    我们知道,每个进程在内核中都有一个进程控制块(PCB)来维护进程相关的信息,Linux内核的进程控制块是 task_struct 结构体。
    /usr/src/linux-headers-3.16.0-30/include/linux/sched.h 文件中可以查看 struct task_struct 结构体定义。其内部成员有很多,我们重点掌握以下部分即可:
在这里插入图片描述
补充

文件id查看指令:ps aux

1.5 进程状态

参考链接

    进程基本的状态有 5 种。分别为新建态,就绪态,运行态,阻塞态与终止态。其中新建态为进程准备阶段,常与就绪态结合来看。在这里插入图片描述

引起进程状态转换的具体原因如下:

  • NULL→新建态:执行一个程序,创建一个子进程。
  • 新建态→就绪态:当操作系统完成了进程创建的必要操作,并且当前系统的性能和虚拟内存的容量均允许。
  • 运行态→终止态:当一个进程到达了自然结束点,或是出现了无法克服的错误,或是被操作系统所终结,或是被其他有终止权的进程所终结。
  • 运行态→就绪态:运行时间片到;出现有更高优先权进程。
  • 运行态→等待态:等待使用资源;如等待外设传输;等待人工干预。
  • 就绪态→终止态:未在状态转换图中显示,但某些操作系统允许父进程终结子进程。
  • 等待态→终止态:未在状态转换图中显示,但某些操作系统允许父进程终结子进程。
  • 终止态→NULL:完成善后操作。

2 进程控制

2.1 fork/getpid/getppid

2.1.1 函数原型

  • pid_t fork(void);失败返回-1;成功返回:① 父进程返回子进程的 ID(非负) ②子进程返回 0
  • pid_t getpid(void);获取当前进程 ID
  • pid_t getppid(void);获取当前进程的父进程 ID

补充:初学者常常有个问题,就是子进程的执行范围:其实子进程只会继续执行fork函数之后的部分…

2.1.2 案例一 打印父子进程id

fork getpid getppid的使用

# include<stdio.h>
# include<stdlib.h>
# include<unistd.h>
int main()
{
   
  pid_t pid ;
  pid = fork();
  if(pid<0)
  {
   
  	perror("fork error");
  	
  }
  else if(pid==0)
  {
   
  	printf("I am child pid =%d my father pid=%d\n",getpid(),getppid());
  }
  else
  {
   
  	printf("I am father pid =%d my father pid =%d\n",getpid(),getppid());
  }
  return 0;
}

在这里插入图片描述

2.1.3 案例二 顺序打印5个进程

通过命令行参数指定创建进程的个数,每个进程休眠 1S 打印自己是第几个被创建的进程。

# include<stdio.h>
# include<stdlib.h>
# include<unistd.h>
int main()
{
   
  pid_t pid;
  int i;
  for(i=0;i<5;i++)
  {
   
  	pid =fork();
  	if(pid==0)
  	{
   
  	 
  • 36
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Windalove

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值