进程ID

每一个进程都有一个唯一的进程ID。几个特殊进程:

  1. 0号进程是内核进程,一般是调度进程swapper。
  2. 1号进程init,是用户进程(以root权限执行/sbin/init),负责初始化。
  3. 几个重要函数:getpid(进程ID)/getppid(父进程ID)/getuid(进程真有用户ID)/geteuid(进程有效用户ID)/getgid(进程真有用户组ID)/getegid(进程有效用户组ID)。

fork/exec/wait例程

fork家族函数用于创建子进程(父子进程关系下节详细介绍),子进程往往调用exec家族函数运行新程序(fork+exec操作在有些系统中被称为spawn孵化),而wait家族函数用于获取子进程终止状态。

system函数使用/bin/sh运行命令,下面是使用fork/exec/wait实现的简单版本号

#include<sys/wait.h>
#include<errno.h>
#include<unistd.h>
int system(constchar *cmdstring) /* version without signal handling */
{
pid_t pid;
int status;
if (cmdstring == NULL)
return(1); /* always a command processor withUNIX */
if ((pid = fork()) < 0) {
status = -1;
} else if (pid == 0) { /* fork返回值为0,表示是在子进程中*/
execl("/bin/sh", "sh","-c", cmdstring, (char *)0);
_exit(127); /* execl error */
} else { /* 在父进程中,fork返回子进程pid */
while (waitpid(pid, &status, 0) < 0) {
if (errno != EINTR) {
status = -1; /* error other than EINTR fromwaitpid() */
break;
}
}
}
return(status);
}
  1. fork函数一次调用,在父进程和自己成中两次返回,由于父进程能够fork多个子进程,所以设计成在父进程中返回子进程pid,而在子进程返回0,由于子进程能够通过getpid和getppid获取自身pid和父进程pid。常见应用场景是在网络编程中,父进程while循环监听用户请求,当接收到用户请求,fork出子进程进行处理。注:linux系统中,fork通过clone系统调用实现。
  2. waipid函数使用參数0等待指定子进程返回,wait函数家族包含wait(等待任一子进程返回)/waitpid(等待指定子进程&组返回,并能通过第三个參数设置堵塞选项)/waittid(进一步扩展,能获取导致进程终止的信号信息等)/wait3(还能够返回进程使用的资源)/wait4(其它wait函数的入口)。
  3. exec家族函数的作用是替换掉当前进程上下文(text/data/heap/stack等),运行新的程序(不会创建新进程)。exec家族函数包含execl/execlp/execle/execv/execvp/execve,各个函数主要差别在參数上,当中l表示是列表形式,v表示是指针数组形式,e表示环境变量,p表示命令參数是相对路径,会在PATH路径中搜索。

父子进程

子进程和父进程共享仅仅读的text段,针对bss段、对、栈,现代操作系统使用COW(copy-on-write)技术,仅仅有发生改变时,才会拷贝对应的内存页。

父子进程关系

子进程会继承父进程的大量属性,当中一些重要属性包含:真实/有效用户信息,进程组/会话信息,工作文件夹,环境变量,资源限制等。

父子进程最明显的差别是:子进程的tms时间统计信息被清零,子进程不会继承文件锁,未决闹钟&信号等(兴许章节讨论)。

子进程和父进程返回先后顺序是不确定的,假设用户程序对父子进程运行顺序有依赖,须要自行处理,比方使用信号实现等待通知机制等。

  1. 内核为每一个正在终止的进程保留了少量信息(pid,终止状态,CPU时间等),便于父进程获取其终止状态。
  2. 假设子进程在父进程之前结束,而父进程没有wait,子进程会变成僵尸进程。
  3. 假设父进程先结束,子进程的父进程会变成init进程(pid为1),所以假设要避免僵尸进程的产生,能够两次调用fork,即在子进程中再次调用fork,然后退出。这样第二个fork出来的进程因为其父进程退出,所以被init进程接管。

文件共享

子进程会dup父进程打开的文件描写叙述符(共享文件描写叙述符close-on-exec标记),包含标准输出、输入和错误输出。

如图,父子进程共享file tableentry,位置偏移量一致,所以要父子进程读写同一文件时要注意同步。

设置进程用户ID

之前提到,子进程会继承父进程的uid和euid(有效用户ID),能够调用setuid(setgid)改动进程用户(组)。

  1. 假设是root用户调用,会同一时候改动进程的uid、euid和备份euid(saved set-user-id)。登陆后,由login(root进程)设置用户ID。
  2. 非root用户仅仅能改动euid,并且仅仅能改动成之前的uid或者备份euid,否则出错。
  3. 假设自进程运行exec方法,并且运行程序的set-user-ID位被设置,那么euid被设置被运行程序属主ID。
  4. 备份euid复制euid。正常情况下,uid=euid=备份euid。
  5. 程序编写遵循“最小权限“模型,当且仅当程序须要高权限时,才调用setuid提升权限,操作完之后再调用setuid恢复权限。

其它进程相关函数

  1. 进程审计:acct开启进程审计功能,系统记录已终止进程的统计信息,包含用户ID,启动时间,CPU时间等。Linux系统审计记录保存在/var/log/account/pacct,须要用fread读取acct结构体信息。
  2. 进程调度:进程调整nice值来设置执行优先级(你越nice,你的优先级越低,人艰不拆。。),相关函数:nice/getpriority/setpriority
  3. 进程时间:调用clock_t times(structtms *buf )函数,当中返回值为时钟时间,而tms结构体被下面内容填充:
struct tms {
clock_t tms_utime; /* user CPU time */
clock_t tms_stime; /* system CPU time */
clock_t tms_cutime; /* user CPU time, terminated children */
clock_t tms_cstime; /* system CPU time, terminated children */
};

注意:相关时间已经通过每秒滴答数(_SC_CLK_TCK)转化成了秒数,但它是从过去任一时间開始统计的,所以其绝对值无意义。一般分别在进程開始和结束调用times,再计算之间的时间差。

读书笔记-APUE第三版-(8)进程控制的更多相关文章

  1. 读书笔记-APUE第三版-(7)进程环境

    本章关注单进程执行环境:启动&终止.參数传递和内存布局等. 进程启动终止 如图所看到的: 启动:内核通过exec函数执行程序,在main函数执行之前.会调用启动例程(start-up rout ...

  2. 《Java 8实战》读书笔记系列——第三部分:高效Java 8编程(四):使用新的日期时间API

    https://www.lilu.org.cn/https://www.lilu.org.cn/ 第十二章:新的日期时间API 在Java 8之前,我们常用的日期时间API是java.util.Dat ...

  3. 读书笔记---PMBOK第五版官方中文版

    以下是为了准备PMP考试时学习<PMBOK第五版官方中文版>这本书的笔记和摘要,目的是为了以后可以快速的抓住本书的核心重点复习. 引论 PMPOK的目的 收录了项目管理知识体系中被普遍认可 ...

  4. 《深入理解bootstrap》读书笔记:第三章 CSS布局

    一. 概述一下理念 bootstrap基于H5开发.提倡移动先行(媒询声明是必须的),对浏览器支持面不是很广. 响应式图片:max-width:100% height:auto; 可以加上:.img- ...

  5. Kafka技术内幕 读书笔记之(三) 生产者——消费者:高级API和低级API——基础知识

    1. 使用消费组实现消息队列的两种模式 分布式的消息系统Kafka支持多个生产者和多个消费者,生产者可以将消息发布到集群中不同节点的不同分区上:消费者也可以消费集群中多个节点的多个分区上的消息 . 写 ...

  6. Kafka权威指南 读书笔记之(三)Kafka 生产者一一向 Kafka 写入数据

    不管是把 Kafka 作为消息队列.消息总线还是数据存储平台来使用 ,总是需要有一个可以往 Kafka 写入数据的生产者和一个从 Kafka 读取数据的消费者,或者一个兼具两种角色的应用程序. 开发者 ...

  7. Linux内核分析 读书笔记 (第三章)

    第三章 进程管理 3.1 进程 1.进程: 进程就是处于执行期的程序. 进程就是正在执行的程序代码的实时结果. 进程是处于执行期的程序以及相关的资源的总称. 进程包括代码段和其他资源. 2.线程:执行 ...

  8. webkit技术内幕读书笔记 (二、三)

    可视区和网页 通常网页比屏幕的可视区面积要大,因此当网页内容在可视区中放不下时,一般浏览器会提供滚动条. 从URL到构建完DOM树的过程 当用户输入网页URL的时候,WebKit调用其资源加载器加载该 ...

  9. Linux内核设计与实现 总结笔记(第三章)进程

    进程管理 进程:处于执行期的程序. 线程:在进程中活动的对象 虚拟机制 虚拟处理器:多个进程分享一个处理器 虚拟内存:多个线程共享虚拟内存 一.进程描述符和任务结构 进程存放在双向循环链表中(队列), ...

随机推荐

  1. (转)链接服务器——获取EXCEL数据

    测试目的:验证利用链接服务器.分布式查询获取EXCEL中的数据测试环境:Microsoft SQL Server 2005 - 9.00.3080.00 (X64)  Enterprise Editi ...

  2. 关于django过滤器的使用

    最近项目中要做分类筛选,其实已经做了这个功能,但是有一个字段是MultiSelectField类型,包含多个值,用户提交的数据是单个值,无法查询出结果, 所以用到了自定义过滤 原代码 class In ...

  3. afl入门学习

    一个简单的示例 安装afl wget http://lcamtuf.coredump.cx/afl.tgz tar xfz afl.tgz cd afl-xxx sudo make install 用 ...

  4. Robots.txt 不让搜索引擎收录网站的方法

    有没有担心过自己的隐私会在强大的搜索引擎面前无所遁形?想象一下,如果要向世界上所有的人公开你的私人日记,你能接受吗?的确是很矛盾的问题,站长们大都忧虑“如何让搜索引擎收录的我的网站?”,而我们还是要研 ...

  5. JS几种变量交换方式以及性能分析对比

    前言 "两个变量之间的值得交换",这是一个经典的话题,现在也有了很多的成熟解决方案,本文主要是列举几种常用的方案,进行大量计算并分析对比. 起由 最近做某个项目时,其中有一个需求是 ...

  6. HDU - 4420 2013icpc长春A 函数离散化 + st表

    思路:我们定义F(x) 为以x点为起点,向后(a - b)个里面有多少个白球,虽然x的范围是LL范围内的,但是白球的 个数只有1e5, 那么我们可以把连续一段相同的离散化到一起, 对于一个确定的长度为 ...

  7. ref:详解MYSQL数据库密码的加密方式及破解方法

    ref:https://blog.csdn.net/paul123456789io/article/details/53081921 MySQL数据库用户密码跟其它数据库用户密码一样,在应用系统代码中 ...

  8. 系统导出数据到excel,数据量过大(大约10W)条,导致服务器 cpu 100%解决方法

    系统导出数据到excel,数据量过大(大约10W)条,导致服务器 cpu 100%解决方法

  9. Home Assistant + 树莓派:强大的智能家居系统 · 安装篇

    Home Assistant + 树莓派:强大的智能家居系统 · 安装篇 转载:Home Assistant + 树莓派:强大的智能家居系统 · 安装篇 目录 1. 初始安装 3. Homebridg ...

  10. iOS Sprite Kit教程之场景的设置

    iOS Sprite Kit教程之场景的设置 Sprite Kit中设置场景 在图2.8所示的效果中,可以看到新增的场景是没有任何内容的,本节将讲解对场景的三个设置,即颜色的设置.显示模式的设置以及测 ...