LINUX操作系统之进程

本文围绕 Linux 进程展开,介绍了程序及多个程序的执行方式,阐述了进程的概念,说明了进程实现并发需借助内存和 CPU,通过 4G 虚拟内存和 CPU 时间分片达成。还提及进程的使用,如创建、资源回收、退出等,并给出相关练习及答案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

linux–进程

1、程序 program

  •   程序 = 数据结构 + 算法
      数据结构 = 数据 + 结构
      算法: 指令的集合
      计算机:执行程序(使用指令 处理 数据)
    

2、 多个程序的执行方式
(1)顺序执行

  •  一个程序执行完毕之后,才能执行下一个程序
      假如:
          a : 输入 计算 输出
          b : 输入 计算 输出
          ====>a: 输入(IO)    计算(CPU)    输出(IO)   b:输入(IO)    计算(CPU)    输出(IO) 	
      	====>CPU 以及 IO利用率低
    
    (2)并发执行
  •   a:输入  计算   输出
      b:      输入   计算   输出
      	=====》并发执行:在重合的时间点上,有多个程序在执行  
    
      并发:在某些时间点内,多个程序同时执行
      并行:在任何一个时间点上,多个程序同时执行
      	=====>为了实现“并发",特地引入了"进程"的概念
    

3.什么是进程?(process)

  • 正在运行的 程序
    进程是具有独立功能的程序 在某个数据集合上的 一次运行活动
process(v 动作的处理过程) 和procedure(n 步骤)的区别:
	(1)程序 是 静态的概念  进程是一个动态的概念(开始  ---》结束)
		main               main运行的时候 
	(2)进程是独立活动单位 是竞争资源的基本单位
	(3)程序中 是 可以启动  多个进程的
thinking:		
	进程1是CPU运行的,CPU发现有更高优先级的进程, 进程1是可以切换到另一进程2(可以抢占的) 
	切换的时候: 
			保存当前进程的所有信息,
	当进程2处理完成,CPU切换回进程1 ,恢复原本保存的信息 继续运行 

3.1进程从生到死 会经历的状态转换
	就绪状态
	阻塞状态
	运行状态
	A 就绪 ---》阻塞   X
	B 就绪----》运行    
	C 阻塞---》运行    X
	D 运行-时间片完--》就绪 

4.进程 如何 实现 并发?
程序: main
运行程序main(即启动一个进程):
(1)把可执行程序的内容 加载 到内存 中
(2)CPU决定执行该进程,CPU开始执行 内存中存储的指令
======>涉及到的硬件?
内存 和 CPU

(1)CPU可以访问的内存空间有多大呢? (x86 linux系统32位)---->4G

4G的内存空间分布(存储的内容):
  int a=10; //.data
  int b;  //.bss 
  int main()
  {
    char* p=malloc(10); //p: 栈     分配的空间(堆)
    char* str1="abcde";//str1:栈  abcde :rodata		
  }

====》每个进程都认为自己有4G的内存。
=====>OS运行多个进程,如果每个进程真正占用4G的内存,
物理内存不够,如何实现的呢?
====>4G 虚拟内存
====>as a code farmer ,我在程序中可以使用4G内存可用

内存操作空间

(2) 如何实现并发?----》 CPU
CPU给每个进程进行时间分片

  •       进程名  1    2    3    4  
          |          |
          |                |   
          |			 	       |
          |                             |
          |        |
          |              |
    

    ====》实现并发,CPU给每个进程一个时间片,在对应的时间片
    运行进程,CPU速度极快,感觉所有程序 在同时运行
    5.使用进程

  • ./main —》运行main的时候,就已经有一个进程了
    (1)创建进程 fork

  •   	#include <unistd.h>
          pid_t fork(void);
      	返回值:
      		如果成功  父进程返回子进程的PID 
      				  子进程返回  0
      		如果失败  -1  errno被设置
      	NOTE:
      		(1)fork之前本身有一个进程,fork之后,创建一个子进程。
      		(2)fork创建的子进程和父进程执行的代码一样的.
      			fork之后子进程的地址空间是 完全从父进程 拷贝的 
      		(3)fork之后创建的进程,运行的先后顺序undefine
      		(4)子进程运行分配资源的,子进程的资源必须要由父进程回收,
      			如果父进程不回收子进程的资源,子进程就会成为僵尸进程 
      			
      			
    父进程比子进程先结束,子进程即成为 孤儿进程(继续运行),会把子进程的交给init
      			(当子进程结束的时候,请init进程回收资源)
      				
    ====保证=>子进程  比父亲进程 先结束
    ====>父进程回收子进程 的资源
    

(2)父进程等待子进程执行结束 回收资源

  •   	   #include <sys/types.h>
      	     #include <sys/wait.h>
      	     pid_t wait(int *status);
      	   功能: 调用进程 等待 子进程状态改变:
      	    ①子进程结束
      	    ②子进程被信号暂停
      	    ③子进程被唤醒了
      	  函数才会返回,否则一直阻塞。
      	  status:NULL 
      	      如果非空,可以使用(*status)来判断子进程退出的信息	
      	      WIFEXITED(status);//是否正常退出
      	      WEXITSTATUS(status)//退出码 
              ..
        返回值:
          成功  返回结束进程的ID号
          失败 返回-1 
    

(3)进程如何退出

  •       主动退出:
            ①当所有的指令执行结束 即(main函数执行结束)
            int main()
            {
              return 0;
            }
      	②使用函数
      		exit :进程正常退出 (清理缓冲区)
      		  #include <stdlib.h>
      		  void exit(int status);
      		  status: 表示进程的退出码
      		  功能:正常退出  &&  status&0377交给父进程
      		_exit  直接退出进程 
                   #include <unistd.h>
      			 void _exit(int status);
      			status:status&0377交给父进程
      			打开文件的文件关闭,子进程交给init进程
    

    练习:

    1.下列程序会创建几个进程?

    int main()
          {
            fork();
            int i;
            for(i=0;i<2;i++)
            {
              fork();
            }
            printf("*************\n");
          }		
    
        答案:8 个
    

    2.下列程序的输出结果是什么?

    •       int main()
            {
              pid_t pid=fork();
              for(i=0;i<1;i++)
              {
                if(pid==0)
                {
                  printf("son\n");
                }else if(pid> 0)
                {
                  wait(NULL);
                  printf("father");		
                  fork();
                }
              }
        
            }//son  father 
      

    答案: son 10,father 11
    3.输出下列程序的执行结果?why?

  •       int a=10;
          int main()
          {
            int pid=fork();
            if(pid==0)
            {
              a++;
              printf("son: %d\n",a);
            }else if(pid>0)
            {
              wait(NULL);	
              printf("father: %d\n",a);
      
            }
            return 0;
      
          }
          son:11 
          father 10
    

    父子进程的 地址空间(虚拟内存)4G 独立。
    父进程 修改的变量 自己的私有地址空间
    子进程 修改的变量 自己的私有地址空间

    4.创建一个进程,子进程进行冒泡排序,父进程输出结果
    答: 父进程输出的一定是:原有的未排序的数组

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值