进程控制

进程创建
  • pid_t fork(void); – 创建一个进程 — 父子进程数据独有,代码共享

写时拷贝技术: 子进程复制了父进程,一开始与父进程指向同一块物理内存;因此看起来父子进程完全相同,但是进程之间具有独立性,意味着当这块物理内存中数据即将发生改变时会重新给子进程开辟物理内存,将数据拷贝过来,因为子进程应该有自己的数据
代码共享: 因为代码段是共有的
进程创建时采用写时拷贝技术,目的是提高进程的创建效率,按理说每个进程应该具有自己独立的内存空间,但是创建子进程时直接开辟空间和拷贝数据,将会比较缓慢,并且拷贝过来的数据子进程从来都不用
子进程创建pcb的时候,就会创建页表,虚拟地址空间……然后从父进程pcb中去拷贝这些数据过来

  • pid_t vfork(void):创建一个子进程,并且会阻塞父进程,直到子进程 exit 退出或者程序替换之后,父进程才会运行

vfork创建子进程效率比较高,因为vfork创建子进程后,父子进程公用同一块虚拟地址空间,意味着公用代码段数据段,这样如果父子进程同时运行会造成栈混乱,因此必须子进程先运行,父进程阻塞,直到子进程退出,所有函数出栈,vofork创建的子进程是不能使用main中return退出的,因为 return 退出会释放进程资源。

进程终止
  • main 函数中 return,退出时会刷新缓冲区
  • void exit(int status) — 库函数,退出调用进程,将status作为返回值给父进程
  • void _exit(int status) — 系统调用接口,退出调用进程,将status 返回给父进程

exit / return 退出时都会刷新缓冲区;_exit退出时直接释放资源,不刷新缓冲区
exit 和 return 的区别:return 之后再main函数中的时候才会退出进程,而exit是在任意位置调用都会退出调用进程

进程等待

作用: 父进程等待子进程的退出,获取子进程的返回值,避免产生僵尸进程

  • pid_t wait(int *status) — 阻塞等待任意一个子进程退出,获取子进程的返回值放到 status 指向的空间中,并且释放子进程资源,返回退出的子进程pid
    阻塞: 为了完成某个功能发起一个调用,若当前不具备完成功能的条件,则调用不返回一直等待
    非阻塞: 为了完成某个功能发起一个调用,若当前不具备完成某个功能的条件,则立即报错;非阻塞操作通常需要循环操作

  • pid_t waitpid(pid_t pid,int *status,int options);
    pid:若 == -1,则表示等待任意一个子进程退出,若是 >0,则表示等待指定子进程退出
    status:输出型参数,传入一个 int 空间的首地址,获取退出的子进程返回值
    options:选项参数,0 – 则表示默认阻塞等待;WNOHANG – 将waitpid设置为非阻塞 – 没有子进程已经退出的话就立即报错返回
    返回值:若等待到了子进程退出则返回子进程的pid;若有子进程但是没有退出则返回0;出错返回 -1
    wait(status)==waitpid(-1,status,0)

status

在这里插入图片描述
进程在终止时并不一定时正常退出,若子进程是异常退出,获取这个返回值则毫无意义,因此获取一个进程返回值的前提是这个进程是正常退出的!
如何判断子进程是否正常退出
在status这个变量中,低 8 位保存了一些特殊数据
在这里插入图片描述

core dump:核心转出 – 程序异常退出时,则保存程序的运行信息,便于时候调试
信号:通知进程发生了某个事件,中断进程当前的操作,去处理这个事件,而操作系统中的信号的体现实际上是一个数字,某个数字表示某个异常时间,程序因为异常退出的时候,则会将这个异常退出时间的信号值放在 低7位
结论:若status低 7位位 0则表示程序正常退出,否则百世程序异常退出
获取子进程的返回值: 0x7f & status

WIFEXITED(status) – 用于根据status判断子进程是否正常退出
WEXITSTATUS(status) – 从status 中取出子进程退出返回值

程序替换

创建一个子进程的目的是什么?

  • 干着跟父进程相同的事情,分摊压力
  • 让子进程干其他事情,让子进程背锅

缺陷: 程序的耦合度非常强,因为所有功能代码都是在当前程序中编写的 – 如果想改变子进程的功能处理流程,需要修改整个程序代码,然后重新编译,这样一来程序就会非常大
程序替换: 替换一个进程正在调度的程序信息(进程是pcb,负责调度管理一个程序的运行,运行的数据和代码都在内存中),将另一个程序加载到内存中,然后让原有的pcb不在调度原程序,而是去调度这个新的程序 。本质来说就是替换一个pcb在内存中对应的代码和数据(加载另一个程序到内存中,然后更新页表信息,初始化虚拟地址空间),这个进程的pcb将从头重新开始调度新的程序运行。

如何实现程序替换:

  • int execl(const char *path,const char *arg,…);
    path 带有路径的新程序名称,就是使用这个程序替换进程正在调度运行的程序, arg 将新程序的运行参数,通过不定参的形式传进新程序,以NULL结尾

  • int execlp(const char *file,const char *arg,…);

  • int execle(const char *path,const char *arg,…,char *const envp[]);

  • int execv(const char *path,char *const argv[]);

  • int execvp(const char *file,char *const argv[]);

  • int execve(const char *path,char *const argv[],char *const envp[]);

l 和 v 的区别:在于程序运行参数的赋予方式不同,l 通过不定参完成 / v 通过字符串指针数组进行赋予
有没有 p 的区别:在于第一个参数执行新程序时,是否需要带路径,有 p 则可以不带路径,默认回去 PATH 环境变量指定路径下查找
有没有 e 的区别:在于这个进程的环境变量是否需要重新初始化;有 e 则表示初始化,若没有 e 则表示使用默认的环境变量

程序替换之后,当前进程运行完替换后的程序就会退出,并不会回去运行原先的程序

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
GeoPandas是一个开源的Python库,旨在简化地理空间数据的处理和分析。它结合了Pandas和Shapely的能力,为Python用户提供了一个强大而灵活的工具来处理地理空间数据。以下是关于GeoPandas的详细介绍: 一、GeoPandas的基本概念 1. 定义 GeoPandas是建立在Pandas和Shapely之上的一个Python库,用于处理和分析地理空间数据。 它扩展了Pandas的DataFrame和Series数据结构,允许在其中存储和操作地理空间几何图形。 2. 核心数据结构 GeoDataFrame:GeoPandas的核心数据结构,是Pandas DataFrame的扩展。它包含一个或多个列,其中至少一列是几何列(geometry column),用于存储地理空间几何图形(如点、线、多边形等)。 GeoSeries:GeoPandas中的另一个重要数据结构,类似于Pandas的Series,但用于存储几何图形序列。 二、GeoPandas的功能特性 1. 读取和写入多种地理空间数据格式 GeoPandas支持读取和写入多种常见的地理空间数据格式,包括Shapefile、GeoJSON、PostGIS、KML等。这使得用户可以轻松地从各种数据源中加载地理空间数据,并将处理后的数据保存为所需的格式。 2. 地理空间几何图形的创建、编辑和分析 GeoPandas允许用户创建、编辑和分析地理空间几何图形,包括点、线、多边形等。它提供了丰富的空间操作函数,如缓冲区分析、交集、并集、差集等,使得用户可以方便地进行地理空间数据分析。 3. 数据可视化 GeoPandas内置了数据可视化功能,可以绘制地理空间数据的地图。用户可以使用matplotlib等库来进一步定制地图的样式和布局。 4. 空间连接和空间索引 GeoPandas支持空间连接操作,可以将两个GeoDataFrame按照空间关系(如相交、包含等)进行连接。此外,它还支持空间索引,可以提高地理空间数据查询的效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值