进程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. 【[SDOI2009]Bill的挑战】

    一看题解好像全是状压DP,那么我就来补充一个容斥写法吧 乍一看,好像是水题,枚举选哪k个串,然后判断 1,如果这k个串中至少两个串某位置确定且不相同,答案显然为02,如果这个位置只被有且仅有一个串确定 ...

  2. Ad Hoc Distributed Queries的启用与关闭

    启用Ad Hoc Distributed Queries: exec sp_configure 'show advanced options',1 reconfigure exec sp_config ...

  3. dp入门题目

    本文文旨,如题... 转载请注明出处... HDOJ 1176 免费馅饼 http://acm.hdu.edu.cn/showproblem.php?pid=1176 类似数塔,从底往上推,每次都是从 ...

  4. MySQL5.6 Waiting for Commit Lock

    mysql  Bug#19843808 自动修复记录 MySQL5.6和Xtrabackup之间存在一个bug,这个bug在5.6.23中已经修复. Xtrabackup备份的时候执行flushs t ...

  5. day8--by a gentlement man

    1.着装得体(不要国产.不要Jack&Johnson.selected),人都是势利眼,高素质和低素质人的区别,高素质是心里明白歧视你,但是不说:低素质是直接表示出来:lower,屌丝     ...

  6. scrapy 设置cookie池

    代码已经很详细了,可以直接拿来使用了. 包含了: 从网页获取cookie 存入mongodb 定期删除cookie scrapy中间件对cookie池的取用 #!/usr/bin/python #co ...

  7. 【LOJ】#2055. 「TJOI / HEOI2016」排序

    题解 看错题了,我以为是询问Q是个数字,问它在哪个位置 我一想这不直接01序列搞一下就好了嘛(事实上是012) 然后呢,我发现样例没过. 啊我看错题了,问的是Q这个位置是啥-- 哦,套用我之前的想法不 ...

  8. 【LOJ】#2562. 「SDOI2018」战略游戏

    题解 圆方树建好之后点是原来的两倍,而st表求lca也要开到点的两倍,所以是四倍 我并没有开小,然而= =,我的预处理log2,写成了200000,而不是400000 我是不是折翼啊= = 很可写,我 ...

  9. Deepin Linux安装MySQL方法

    sudo apt-get install mysql-server apt-get install mysql-client sudo apt-get install libmysqlclient-d ...

  10. java_String、StringBuilder

    在介绍String和StringBuilder前先学习一下equals方法和toString方法.API java1.6提取码:04b6 equals方法 equals方法,用于比较两个对象是否相同, ...