Linux编程(9)_进程
1 进程相关概念
1 程序和进程
程序: 二进制文件, 占用的磁盘空间
进程: 启动的程序, 所有数据都在内存, 不仅占用内存空间, 也需要占用更多的系统资源, 例如CPU, 物理内存
2 并行和并发
如图所示: 并发是两个队列交替使用一台咖啡机,并行是两个队列同时使用两台咖啡机
并发: 在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。
并行: 是指“并排行走”或“同时实行或实施”。在操作系统中是指,一组程序按独立异步的速度执行,同一个时刻发生。要区别并发。并发是指:在同一个时间段内,两个或多个程序执行,有时间上的重叠(宏观上是同时,微观上仍是顺序执行)。
3 pcb 进程控制块
每个进程在内核中都有一个进程控制块(PCB)来维护进程相关的信息, Linux内核的进程控制块是task_struct结构体
内部成员很多, 重点有:
- 进程id. 系统中每个进程有唯一的id, 在C语言中用pid_t类型表示, 是一个非负整数
- 进程的状态. 有就绪, 运行, 挂起, 停止等状态
- 进程切换时需要保存和恢复的一些CPU寄存器
- 描述虚拟地址空间的信息
- 描述控制终端的信息
- 当前工作目录
- umask掩码
- 文件描述符表(1024), 包含很多只想file结构体的指针
- 和信号相关的信息
- 用户id和组id
- 会话(Session)和进程组, 会话有多个进程组组成
- 进程可以使用的资源上限(Resource Limit)
4 进程状态的切换
2 进程控制
1 fork
int fork(void)
生成父进程和子进程, 有两个返回值, 分别由父进程和子进程返回. 父进程返回子进程的PID, 子进程返回0, 出错则返回-1.
fork之后的变量读时共享, 写时复制.
fork函数的返回值
>0, 父进程的返回值
=0, 子进程的返回值
子进程创建成功之后, 代码执行位置
从父进程执行的位置开始执行, 忽略之前的代码
父子进程的执行顺序
不一定, 看谁先抢到cpu
如何区分父子进程(通过返回值)
getpid()
获取当前进程的id
getppid
获取当前进程父进程的id
2 循环创建进程
int main()
{int i = 0;int number = 5;pid_t pid;for(int i=0; i<number; ++i){pid = fork();if(pid == 0) // 子进程跳出循环 break; }//如何判断是第几个孩子//通过循环因子判断// 父进程if(i == 3){counter += 100;printf("parent process, pid = %d, ppid = %d, %d\n", getpid(), getppid(), counter);// sleep(1);}// 子进程else if(i == 0){// 1thcounter += 200;printf("child process, pid = %d, ppid = %d, %d\n", getpid(), getppid(), counter);}else if(i == 1){// 2thcounter += 300;printf("child process, pid = %d, ppid = %d, %d\n", getpid(), getppid(), counter);}else if(i == 2){// 3thcounter += 400;printf("child process, pid = %d, ppid = %d, %d\n", getpid(), getppid(), counter);}return 0;
}
3 进程相关命令
ps
ps aux | grep "xxx"
搜索进程ps ajx | grep "xxx"
更加全面的搜索进程kill
向指定的进程发送信号查看信号
kill -l
杀死某个进程
kill -9 PID
3 exec函数族
让父子进程执行不相干的操作
实现换核不换壳的功能
执行一个另外的程序不需要创建额外的地址空间
在当前程序调用另外一个的程序
首先想到exec之前需要fork
如果函数执行成功, 没有返回值, 如执行失败, 打印错误信息, 退出当前进程.
1 执行指定目录下的程序
原型
int execl(const char *path, const char *arg, ...)
;path: 要执行的程序的路径
变参arg: 要执行的程序的需要的参数
第一个arg: 占位, 通常写执行程序的名字
后面的arg: 命令的参数
参数写完之后: NULL
一般执行自定义程序
2 执行PATH环境变量里面的程序
原型
int execp(const char *file, const char *arg, ...);
file: 执行的命令的名字
第一个arg: 占位
后边的arg: 命令的参数
参数写完后: NULL
执行系统自带的程序, 会在自动在目录/bin里搜索
例
execlp("ps", "ps", "aux", NULL)
4 进程回收
1 孤儿进程
父进程已经被杀死, 子进程被init进程领养, init进程变成孤儿进程的父亲, ubuntu16.04变成被ui进程领养upstart
为了释放子进程占用的系统资源, 进程结束之后, 能够释放用户区空间, 释放不了pcb, 必须由父进程释放
2 僵尸进程
孩子进程被杀死, 父进程还活着, 爹不去释放子进程的pcb, 孩子进程就变成了僵尸进程
是一个已经死掉的进程
3 进程回收
wait 阻塞函数
pid_t wait(int* status);
返回值: -1: 失败, 已经没有子进程了. >0: 回收的子进程对应的pid
参数: status 判断子进程是如何死的, 正常退出,或被某个信号杀死了
调用一次只能回收一个子进程
waitpid –
- pid_t waitpid(pid_t pid, int *status, int options);
5 进程相关函数
pid_t fork(void);
○ 返回值:
成功: □ 对于父进程来说返回子进程ID
□ 对于子进程来说返回值为0
失败
□ 如果为-1表示创建失败
获取当前进程ID
pid_t getpid(void);
○ 返回值:当前进程ID获取当前进程的父进程ID
pid_t getppid(void);
○ 返回值:前进程的父进程ID
获取当前进程实际用户ID
uid_t getuid(void);
○ 返回值:当前进程实际用户ID
获取当前进程使用用户组ID
gid_t getgid(void);
○ 返回值:前进程使用用户组ID
int execl(const char *path, const char *arg, ...);
○ 函数描述:加载一个进程,通过路径 + 程序名来加载。
函数参数:
§ path:程序路径+程序名字
§ arg:可执行程序的相关参数,使用NULL结尾返回值:
§ 成功:无返回
§ 失败:-1int execlp(const char *file, const char *arg, ...);
函数描述:加载一个进程,借助PATH环境变量,
该函数需要配合PATH环境变量来使用,
当PATH中所有目录搜索后没有参数1则出错返回
函数参数:可执行程序的相关参数,使用NULL结尾
file:可执行程序的名字
arg:可执行程序的相关参数,使用NULL结尾
返回值:
成功:无返回
失败:-1pid_t wait(int *status);
函数作用:
① 阻塞并等待子进程退出
② 回收子进程残留资源
③ 获取子进程结束状态(退出原因)。
返回值:
成功:清理掉的子进程ID;
失败:-1 (没有子进程)
参数:子进程的退出状态 – 传出参数
1. WIFEXITED(status):为非0 → 进程正常结束
WEXITSTATUS(status):
如上宏为真,使用此宏 → 获取进程退出状态 (exit/return)的参数)
2. WIFSIGNALED(status):为非0 → 进程异常终止
WTERMSIG(status):
如上宏为真,使用此宏 → 取得使进程终止的那个信号的编号。pid_t waitpid(pid_t pid, int *status, in options);
函数作用:指定回收某个子进程
参数:
① pid:
pid == -1
回收所有子进程
- 循环回收
-while((wpid = waitpid(-1, $status, xx)) != -1)
???
pid > 0
某个子进程的PID
pid == 0
回收当前进程组的所有子进程
pid < -1
子进程的PID取反
② status: 子进程的退出状态,用法同wait函数
③ options:
设置为WNOHANG,函数非阻塞
设置为0,函数阻塞
返回值:
>0
:返回回收的子进程ID;
-1
:回收失败, 无子进程
如果为非阻塞:=0
子进程正在运行。
Linux编程(9)_进程相关推荐
- Linux编程(10)_进程通信
1 进程通信相关概念 1 什么是IPC 进程间通信, InterProcess Communication 2 进程间通信常用几种方式 管道 (使用最简单) 信号 (开销最小) 共享内存/映射区 (无 ...
- linux编程取消wait函数,Linux编程基础之进程等待(wait()函数).pdf
Linux编程基础之进程等待(wait()函数) 编程过程中,有时需要让一个进程等待另一个进程 ,最常见的是父进程等待自己的子进程 ,或者父进程回收自己 的子进程资源包括僵尸进程.这里简单介绍一下系统 ...
- linux编程学习_您需要编程技能才能学习Linux吗?
linux编程学习 几个月前,我参加了edX提供的Linux入门课程. 这是一门18章的课程,其中包含大量阅读材料,一些视频以及随意测试知识水平的课程. 我写了关于前六章的内容,以及该课程的工作原理, ...
- Linux编程入门四进程
进程的创建有两种方式:一种是由操纵系统创建,一种是由父进程创建.在系统启动时,操作系统会创建一些进程,它们承担着管理和分配系统资源的任务,这些进程通常被称为系统进程.系统允许一个进程创建新进程(即为子 ...
- linux编程基础_第1篇 Linux系统编程 -多线程基础
进程 在理解线程之前,首先需要了解UNIX/Linux进程. 进程是由操作系统创建的,需要相当数量的"开销". 进程包含有关程序资源和程序执行状态的信息,包括:它是一个在随机访问内 ...
- 【Linux编程】守护进程(daemon)详解与创建
本文主要参考自:linux系统编程之进程(八):守护进程详解及创建,daemon()使用 一.概述 Daemon(守护进程)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等待处 ...
- linux ps-e和-ax区别,Linux编程 6 (查看进程 ps 及输出风格)
一.查看进程命令ps 1.1 默认ps 命令 在默认情况下,ps命令只会显示运行在当前控制台下,属于当前用户的进程,在上图中,我们只运行了bash shell以及ps命令本身. 上图中显示了程序的进程 ...
- Unix/Linux编程:fork()进程详解
文章目录 理论 进程 fork,wait,exec fork 实践 验证 `fork函数被调用一次但返回两次` 子进程和父进程之间不共享数据空间 父子进程间的文件共享 fork的内存语义 同步信号以规 ...
- linux进程signal,Linux 编程之【进程】signal
[说明] kill,可以向包括本身在内的进程发送一个信号. kill有一个变体叫 killall,可以给运行着某一命令的所有进程发送信号. pause,将程序挂起直到有一个信号出现为止. 程序中信号的 ...
最新文章
- 项目延期半年,我被软件外包坑惨了!
- python培训班哪些比较好-南京Python培训机构哪家比较好
- router3 BGP2 属性及选路
- 从网上发现的经典js脚本
- Android Studio使用说明
- 关于mysql的一些问题
- 学习Dubbo 影院模块 所得所获?
- python xlwings追加数据_大数据分析Python库xlwings提升Excel工作效率教程
- Python助力中学数学教学:绘图验证反比例函数与矩形交点的关系
- 总结之Unix的基础知识
- Google Earth Engine——Landsat (数据介绍)GEE数据到底是否满足几何和辐射校正?
- java 常用报表控件_常用的Java开源报表工具汇总
- 组合优化中的P问题,NP问题,NP-complete问题和NP-hard问题
- 知识对话2021《Augmenting Knowledge-grounded Conversations with Sequential Knowledge Transition》论文解读
- 【Day1.4】奢华的海滨酒店,打发半天时间不成问题
- mac下安装photoshop
- C语言——函数(上)
- 前端文件下载兼容方案(兼容主流浏览器,包括IE与Safari)
- 利用excel表建立一元线性回归方程
- 苏黎世大学计算机研究生费用,苏黎世联邦理工学院学费需要多少
热门文章
- Jetty与Tomcat的区别 转
- 《从零开始学习jQuery》及《jQuery风暴》学习笔记
- 新手学习jQueryEasyUI
- InstallShield 2012 Spring新功能试用(12): Suite/Advanced UI 和 Advanced UI 工程支持InstallScript安装程序(Part 1)...
- CSDN签约慧安金科,共建全方位智能风控体系
- hash进阶:使用字符串hash乱搞的姿势
- python 列表list相关知识
- 钉钉自带浏览器版本过低,导致Object.assign不兼容...
- libz.dylib的研究 libz.1.2.5.tbd
- 一 对国家出路的早期探索