2018-05-27 21:23:48 lws123253 阅读数 3025

Linux 中的进程睡眠状态有两种:一种是可中断的睡眠状态,其状态标志位为TASK_INTERRUPTIBLE;另一种是不可中断的睡眠状态,其状态标志位为TASK_UNINTERRUPTIBLE。

可中断的睡眠状态的进程会睡眠直到某个条件变为真,如产生一个硬件中断、释放进程正在等待的系统资源或是传递一个信号都可以是唤醒进程的条件。

不可中断睡眠状态与可中断睡眠状态类似,但是它有一个例外,那就是把信号传递到这种睡眠状态的进程不能改变它的状态,也就是说它不响应信号的唤醒。

2015-07-17 16:26:59 liuxiaowu19911121 阅读数 1724

1.Linux系统的进程有几种状态:

TASK_RUNNING(运行状态),
TASK_INTERRUPTIBLE(可被信号中断的睡眠状态),
TASK_UNINTERRUPTIBLE(不可被信号中断的睡眠状态).

其中处于TASK_RUNNING状态的进程由一颗红黑树组织在一起.俗称运行队列.

处于TASK_INTERRUPTIBLE和TASK_UNINTERRUPTIBLE状态的进程由队列组织在一起,俗称等待队列.

等待队列有很多个,每个队列都代表着一种阻塞某个进程的条件,比如因为某个信号量已被占用,而组织在一个队列上的所有进程,比如因为读某个设备的数据时,该设备此时没有数据,这样又构成一个队列

2.进程的睡眠过程:

1.进程将自己加入一个wait_queue_t(等待队列项),然后调用add_wait_queue()将该等待队列项加入某个等待队列中

2.设置进程自己的状态为TASK_INTERRUPTIBLE或TASK_UNINTERRUPTIBLE

3.调用schedule()函数选择一个优先级最高的进程运行,而且schedule函数会调用dequeue_entity()把该进程从 
运行队列中删除

睡眠过程的代码:

    DEFINE_WAIT(wait);
    add_to_queue(q, &wait);
    set_current_stat(TASK_INTERRUPTIBLE);
    if(!condition)
        schedule();
    remove_to_queue(q, &wait);      //醒来后, 把自己移除等待队列
    set_current_stat(TASK_RUNNING); //防止schedule()没执行的情况

3.进程的唤醒过程:

1.wake_up唤醒函数调用try_to_wake_up()函数将进程的状态设置为TASK_RUNNING,并调用enqueue_entity()把该
进程加入运行队列

2.如果新唤醒的进程优先级比当前正在运行的进程优先级更高,则调用schedule()函数进行进程切换. 如果进程优先级没有当前进程的高,则会等待,直到自己变为运行队列中优先级最高时为止

3.该被唤醒的进程重新运行后,会调用remove_wait_queue()将自己从等待队列中删除. //上面睡眠过程的最后两行代码

唤醒过程的代码:

    wake_up(p);

本文引述自 http://edsionte.com/techblog/archives/1854

2011-05-08 09:07:00 pingLinux 阅读数 822

      UNIX中每个进程都有一个优先数,就绪进程能否占用处理器的优先权取决于进程的优先数,优先数越小则优先权越高。
  UNIX以动态方式确定优先权,如核心的进程优先权高于进入用户态的进程;降低用完一个时间片的进程的优先权;对进入睡眠的进程,其等待事件越急优先数越高;降低使用处理器时间较长的进程的优先权。
  UNIX中确定进程优先数的方法有两种:设置方法和计算方法。前者对要进入睡眠状态的进程设置优先数,若等待的事件急迫,则设置较小的优先数;后者用户进程正在或即将转入用户状态运行时确定优先数。

2006-07-02 21:43:00 Idleman 阅读数 1100

1.进程

进程的状态

Unix通过对进程的管理来管理用户、和系统地各种命令和程序的执行。

进程的状态:就绪、运行、睡眠

状态的切换

ps 获取进程的状态信息

选项 -e:显示系统中所有活动进程的信息

选项 -f:显示进程的详细信息

TTY ? 表示是系统后台进程

sleep 暂停进程的运行

$ sleep 10; who

$ echo “I am sleeping...”; sleep 10; echo “I am awake”

kill 终止进程的活动

Kill PID // 正常结束进程

kill -1 PID // 挂起进程,终止子进程,终止进程

kill -9 PID //立即终止进程,不处理子进程

前台进程、后台进程

前台进程:从终端上启动,并且与终端交互

后台进程:与启动的终端不交互



后台进程的启动方式:&

$ ls -R > file &



Kill // 通常用于后台进程

Ctrl+c DEL // 用于前台进程

进程的生存周期

查看当前ShellPID: $echo $$

进程的环境

1) 进程之间存在父子间的层次关系;2) 子进程创建时会从父进程继承很多重要的信息

守护进程(daemons)

通常用来控制系统的资源,一直运行

常见的守护进程:corn, qdaemon, errdaemon

2.系统管理

磁盘管理

df 查询磁盘空间使用情况

Du 指定目录及其子目录的磁盘使用情况

选项 -a

文件系统管理

Fsck 检查和修复文件系统的error

文件的存储与备份

Tar -cvs target file1, file2, file3 ... // create

tar -tvf target // list

tar -xvf target [file] // extract



$ tar -cvf /dev/tape ./src/*.c

系统的启动和终止

Init 系统初始化控制进程

根据/etc/initab文件的描述建立各个系统的进程

系统关机

Shutdown [-hr] time [message]

-h: halt

-r: reboot

time: now | 17:30 | +5

文件的加密与压缩

加密

$ crypt < file > file.cry // 加密

$ crypt < file.cry > file // 解密

$ vi -x file.cry

注:自动识别文件是否加密

压缩

Compress

uncompress

定时执行任务

用户定时执行任务 at

$ at 15:30

who >> userlist

^D

注:默认将执行结果用邮件发送给调用者

系统定时执行任务 cron

通常在 /usr/spool/cron/crontabs目录中包含:用户定时任务描述文件

系统启动时,cron读取这些描述文件,在指定的时间执行规定的任务



任务描述文件的管理

crontab -e [username] //edit

crontab -l [username] //list

crontab -r [username] //remove

 
2019-08-29 14:22:35 qq_36321889 阅读数 68

第二章 核心导言

UNIX操作系统的体系结构

核心框图,给出各种模块及他们之间的相互关系,其中文件系统和进程管理是最核心部分:
在这里插入图片描述
翻译成系统调用界面有点low,应该是系统调用接口叭,为什么将存储管理放置到进程管理当中呢,应该切分出来叭,毕竟存储管理、内存管理、缓存管理那块重要程度也是挺高的,既然挺重要为什么不抽离出来呢!

什么是所谓的宏内核、微内核呢?
见知识补充-微内核与宏内核-笔记

系统概念介绍

文件子系统概述

一个文件的内部表示由一个索引节点(inode)给出,inode:index node,每个文件都有一个索引结点,但是它可以有几个名字,且这几个名字都映射到索引节点上,每个名字称为一个联结。

索引结点存储在文件系统中,但是当操纵文件时,核心把它们读到内存索引节点表中。

核心还包含另外两个数据结构,文件表和用户文件描述符表。文件表是一个全程核心结构,但是用户文件描述符表对每个进程分配一个。也就是说和文件系统有关的有三个表:文件表、用户文件描述符表、索引结点表,当一个进程打开或建立一个文件时,核心在每个表中都相应于该文件的索引节点分配一个表项。

文件表保存文件中的字节偏移,用户文件描述符表标识着一个进程的所有打开文件。

核心在逻辑上只涉及文件系统,不涉及磁盘,每个文件系统都当作由一个逻辑设备号标识的逻辑设备。

一个文件系统由一个逻辑块序列组成,每个块都包含512、1024、2048个字节或512个字节的任意倍数。下文都是以来讲解的。

一个文件系统具有如下数据结构:
[外链图片转存失败(img-xkGjHga9-1567059429772)(en-resource://database/3080:1)]
引导块:可以包含引导操作系统的引导代码,虽然为了引导系统只需要一个代码块,但每个文件系统都有一个引导块,当然可能是空的。

超级块:描述了文件系统的状态—它有多大,它能储存多少文件,在文件系统的何处可找到空闲空间,以及其他信息。

索引节点表:在执行了系统调用mount之后,该文件系统的目录结构就可以从这个根索引结点开始存取了。

数据块:包含文件数据与管理数据

进程

用实际的术语来说,UNIX系统上的进程是被系统调用fork所创建的实体。除了0进程以外,每个进程都是被另一个进程执行系统调用fork时创建的。0进程是系统引导后手动创建的,在它创建了一个子进程1后,0进程就变成了对换进程。1进程被称为init进程,是系统中其他每个进程的祖先,并且享有同它们之间的特殊关系。

可执行文件由以下几部分组成:

  1. 描述文件属性的一组“头标”
  2. 程序正文
  3. 数据的机器语言表示,它给出程序开始执行时的初值;一个空间指示,它指出核心应该为被称为bss的未初始化数据分配多大的空间;
  4. 其他段,诸如符号表信息;

一般都会有:代码段(程序正文)、数据段(bss段)、堆栈段

因为UNIX系统中的一个进程能在两种态—和心态和用户态下执行,所以UNIX系统中核心栈与用户栈是分开的。

系统调用的过程:每个系统调用都在系统调用库中有一个入口点,系统调用库按汇编语言编码并包含一个特殊的trap指令,当该指令被执行时,它引起一个中断,从而导致硬件转换到核心态。

执行核心态代码时,使用核心栈。

后面几章讨论的进程表中的字段是:

  1. 状态字段
  2. 标识符—指出拥有该进程的用户
  3. 当一个进程被挂起时的事件描述符集合

u区包含的是用来描述进程的信息,这些信息仅当进程正在执行时才需要被存取,重要的字段是:

  1. 指向当前正在执行的进程的进程表项的指针;
  2. 当前系统调用的参数,返回值以及错误码
  3. 所有的打开文件的文件描述符
  4. 内部IO参数
  5. 当前目录和当前根
  6. 进程以及文件大小的限度

u区在Linux内核中还存在嘛?

进程上下文

当执行一个进程时,系统被说成在该进程的上下文中执行,当核心决定它应该执行另一个进程时,它做一个上下文切换,以使系统在另一个进程的上下文中执行。

从用户态到核心态的转变并不涉及到上下文切换,上下文并没有切换,仅仅换了一个状态;

中断产生时,从用户态切换到核心态,并且保留足够的上下文信息,以便后续恢复,然后再核心态下对中断进行服务,核心并不产生或调度一个特殊进程来处理中断。

进程状态

用户态-执行
核心态-执行
就绪状态
进程正在睡眠

状态转换

[外链图片转存失败(img-0DCwvXVA-1567059429773)(en-resource://database/3082:1)]
核心少不了cli,sti,为了保证一致性叭!!!

在核心态下运行的进程不能被其他进程所抢占,因此核心有时被称为不可抢先的,所以核心能保证它的数据结构一致性,从而解决了互斥问题,不能抢占的方式包含:不允许调度、关掉中断!

这里需要指出Linux和Unix的一个区别,Linux2.6及更高版本的内核是可以被抢占的,Unix的内核不能被抢占;

什么叫核心态不能抢占呢?

  • 得先弄明白什么时候进入核心态,大多时候都是系统调用叭?
  • 先假设只讨论系统调用时进入核心态,emmm,不会讨论,之后查资料叭

但是如果关掉中断的话,可能导致中断的服务推迟,或者可能会损害系统吞吐量,为此,改为当进入代码临界区时,核心把处理机执行级提高,以禁止中断!,事实上,Linux0.11中直接关掉了中断
[外链图片转存失败(img-Fottu4y9-1567059429774)(en-resource://database/3084:1)]

睡眠与唤醒

一个中断处理程序不能去睡眠,因为如果中断处理程序去睡眠,就意味着将被中断的进程投入睡眠;

睡眠进程不耗费CPU资源,但是进行上下文切换的过程会影响CPU利用,核心并不是经常去查看一个进程是否仍处于睡眠状态,而是等待事件的发生,那时把进程唤醒。

下图所示的代码片段频繁出现在Linux内核程序中:
[外链图片转存失败(img-DDMZsqwo-1567059429775)(en-resource://database/3086:1)]

很关键的一点是不要使用:

if(条件为真)
    sleep(事件:条件变为假)
置条件为真

而应该使用

while(条件为真)
    sleep(事件:条件变为假)
置条件为真

有了上面基础再去看Linux内核源码就会感觉简单很多!!!

核心数据结构—思想层面

大多数核心数据结构都是占据固定长度的表,而不是动态地分配空间,这一方法的优点是核心代码简单高效。

一般认为核心算法的简单性比挤出内存中每一个仅有的字节的必要性更重要。典型地,算法使用简单的循环,以寻找表中的空闲表项,这是一个较易于理解的方法,而且有时比复杂的分配方案更为有效。

系统管理

管理进程和普通进程类似,只是管理进程的权限稍微大了一点,但是核心并不识别一个分立的管理进程。

本章小结

主要描述了文件系统和进程系统;

其中文件系统控制用户文件中数据的存储与检索,每个文件系统都有一个用来描述文件系统的结构和内容的超级块,并且文件的索引都是通过inode来完成的。inode:index node。

核心态不能被抢占意味着:核心态下的进程将连续执行,直至它进入睡眠状态或直至它返回到用户态下执行为止,维护数据的一致性是可以的,但是核心不可抢占是十分影响实时性的;

核心态通过实施不可抢占策略以及通过在执行代码临界区时封锁中断来维护它的数据结构的一致性。

还是需要去查资料,去了解Unix和Linux的区别,从本书的描述和Linus的代码中也能看出一些区别,不过查资料得到知识相对来讲能让看代码的过程更加明确;

进程与上下文

阅读数 595

没有更多推荐了,返回首页