当前位置: 首页 > news >正文

常州溧阳市建设局网站seo是什么及作用

常州溧阳市建设局网站,seo是什么及作用,深圳有做网站最近价格,大连seo按天付费目录 关于进程的基本概念 进程描述符 查看进程 进程标识 进程的生命周期 僵尸进程、孤儿进程 写时拷贝技术 fork()函数 vfork()函数 终止进程 进程优先级和权重 进程地址空间 关于进程的基本概念 进程和程序是操作系统领域的两个重要的概念,进程是执行…

目录

关于进程的基本概念

进程描述符

查看进程

进程标识

进程的生命周期 

僵尸进程、孤儿进程

写时拷贝技术

fork()函数

vfork()函数

终止进程

进程优先级和权重

进程地址空间


关于进程的基本概念


进程和程序是操作系统领域的两个重要的概念,进程是执行中的程序,即一 个程序加到内存后变成了进程,公式表达如下:

进程=程序+执行

程序通常是指完成特定任务的一个有序指令集合或者一个可执行文件,包含可运行的CPU指令和相应的数据等信息,它不具有“生命力”。

进程是一段执行中的程序, 是一个有“生命力”的个体。一个进程除了包含可执行的代码(如代码段),还包含进程的一些活动信息和数据,如用来存放函数形参、局部变量以及返回值的用户栈,用于存放进程相关数据的数据段,用于切换内核中进程的内核栈,以及用于动态分配内存的堆等。进程是用于实现多进程并发执行的一个实体,实现对CPU的虚拟化,让每个进程都认为自已独立拥有一个CPU。实现这个CPU虚拟化的核心技术是上下文切换以及进程调度。

进程描述符

进程是操作系统中调度的一个实体,需要对进程所拥有的资源进行抽象,这个抽象形式称为进程控制块(PCB), 也称其为进程描述符。进程描述符需要描述如下几类信息。

  • 进程的运行状态: 包括就绪、运行、等待阻塞、僵尸等状态。
  • 程序计数器: 记录当前进程运行到哪条指令了。
  • CPU寄存器: 主要用于保存当前运行的上下文,记录CPU所有必须保存下来的寄存器信息,以便当前进程调度出去之后还能调度回来并接着运行。
  • CPU调度信息: 包括进程优先级、调度队列和调度等相关信息。
  • 内存管理信息: 进程使用的内存信息,如进程的页表等。
  • 统计信息:  包含进程运行时间等相关的统计信息。
  • 文件相关信息: 包括进程打开的文件等。


因此进程描述符是用于描述进程运行状况以及控制进程运行所需要的全部信息,是操作系统用来感知进程存在的一个 非常重要的数据结构。任何一个操作系统的实现都需要有一个数据结构来描述进程描述符,所以Linux内核采用一个名为task_struct 的结构体。task_struct 数据结构包含的内容很多,它包含进程所有相关的属性和信息。在进程的生命周期内,进程要和内核的很多模块进行交互,如内存管理模块、进程调度模块以及文件系统模块等。因此,它还包含了内存管理、进程调度、文件管理等方面的信息和状态。Linux 内核把所有进程的进程描述符task_struct数据结构链接成一个单链 表( task_struct->tasks), task_struct 数据结构定义在include/linux/sched.h文件中。

task_struct 数据结构包含的内容可以简单归纳成如下几类。

  • 进程属性相关信息。
  • 进程间的关系。
  • 进程调度相关信息。
  • 内存管理相关信息。
  • 文件管理相关信息。
  • 信号相关信息。
  • 资源限制相关信息。

进程间的关系

操作系统的第一个进程是空闲进程(或者叫作进程0)。此后,每个进程都有一个创建它的父进程,进程本身也可以创建其他的进程,父进程可以创建多个进程。进程类似于一个家族,有父进程、子进程,还有兄弟进程。task_struct数据结构中涉及进程间关系的重要成员如下。

  • real_parent成员: 指向当前进程的父进程的task_ struct数据结构。
  • children成员: 指向当前进程的子进程的链表。
  • sibling成员: 指向当前进程的兄弟进程的链表。
  • group_leader成员: 进程组的组长。

进程调度相关信息

进程一个很重要的角色是作为一个调度实体参与操作系统中的调度,这样就可以实现CPU的虚拟化,即每个进程都感觉直接拥有了CPU。宏观上看,各个进程都是并行执行的,但是微观上看每个进程都是串行执行的。进程调度是操作系统中的个核心功能。

内存管理和文件管理相关信息

进程在运行之前需要先加载到内存,因此进程描述符里必须有抽象描述内存管理的相关信息,必须有一个指向mm_struct数据结构的指针mm。此外,进程在生命周期内总是需要通过打开文件、读写文件等操作来完成一些任务,这就和文件系统密切相关了。task_struct数据结构中与内存管理和文件管理相关的重要成员如下。

  • mm成员:指向进程所管理的内存中总的抽象数据结构mm_struct.
  • fs成员:保存一个指向文件系统信息的指针。
  • files成员:保存一个指向进程的文件描述符表的指针。

查看进程

1. ps命令

ps命令是最基本的进程查看命令,可确定有哪些进程正在运行、进程的状态、进程是否结束、 进程是否僵死、哪些进程占用了过多的资源等等。ps命令最常用的还是监控后台进程的工作情况,因为后台进程是不与屏幕键盘这些标准输入进行通信的。其基本用法为

ps   [选项] 

常用的选项有:  

  • a: 显示系统中所有用户的进程; 
  • x: 显示没有控制终端的进程及后台进程;
  • -e: 显示所有进程
  • r: 只显示正在运行的进程;
  • u: 显示进程所有者的信息;
  • -f: 按全格式显示(列出进程间父子关系); 
  • -l:按长格式显示。

注意有些选项之前没有连字符(-)。如果不带任何选项,则仅显示当前控制台的进程。

最常用的是使用aux选项组合。例如:

 USER表示进程的所有者; PID 是进程号;%CPU表示占用CPU的百分比;%MEM表示占用内存的百分比; VSZ表示占用虚拟内存的数量: RSS表示驻留内存的数量;TTY表示进程的控制终端(值 “?”  说明该进程与控制终端没有关联); STAT表示进程的运行状态(R代表准备就绪状态,S是可中断的休眠状态,D是不可中断的休眠状态,T是暂停执行,Z表示不存在但暂时无法消除,w表示无足够内存页面可分配,<表示高优先级,N表示低优先级,L表示内存页面被锁定,S表示创建会话的进程,1表示多线程进程,+表示是一个前台进程组 ); START是进程开始的时间; TIME是进程已经执行的时间; COMMAND是进程对应的程序名称和运行参数。

通常情况下系统中运行的进程很多,可使用管道操作符和less (或more )命令来查看:

ps aux | less

还可使用grep命令查找特定进程。若要查看各进程的继承关系,使用pstree命令。 

2. top命令
ps命令仅能静态地输出进程信息,而top命令用于动态显示系统进程信息,可以每隔一短时间刷新当前状态,还提供一组交互式命令用于进程的监控。基本用法为:

top [选项]

选项

  • -d指定每两次屏幕信息刷新之间的时间间隔,默认为5s; 
  • -s表示top命令在安全模式中运行,不能使用交互命令; 
  • -c表示显示整个命令行而不只是显示命令名。如果在前台执行该命令,它将独占前台,直到用户终止该程序为止。


在top命令执行过程中可以使用一些交互命令。 例如:按空格将立即刷新显示;按<Ctrl>+<L>键擦除并且重写。

这里给出一个简单的例子:

首先显示的是当前进程的统计信息,包括用户(进程所有者)数、负载平均值、任务数、CPU占用、内存和交换空间的已用和空闲情况。然后逐条显示各个进程的信息,其中进程指的是PID; USER表示进程的所有者; PR表示优先级: NI表示nice值(负值表示高优先级,正值表示低优先级); VIRT 表示进程使用的虚拟内存总量(单位kb ); RES表示进程使用的、未被换出的物理内存大小(单位kb); SHR表示共享内存大小; S表示进程状态(参见ps命令显示的STAT ); %CPU和%MEM分别表示CPU和内存占用的百分比; TIME+ 表示进程使用的CPU时间总计(单位1/100秒); COMMAND是进程对应的程序名称和运行参数。

进程标识

在创建时会分配唯一的号码来标识进程, 这个号码就是进程标识符(PID)。PID存放在进程描述符的pid字段中,PID是整数类型。为了循环使用PID,内核bitmap机制来管理当前已经分配的PID和空闲的PID, bitmap 机制可以保证每个进程仓创建时都能分配到唯一的 PID。

通过使用系统调用函数,getpid和getppid即可分别获取进程的PID和PPID。

 

进程的生命周期 

虽然每个进程都是一个独立的个体,但是进程间需要相互沟通和交流,如文本进程需要等待键盘的输入。

  • TASK_RUNNING (可运行态或者就绪态或者正在运行态---R): 这个状态的名字是正在运行的意思,可是在Linux内核里不一定是指进程正在运行,所以很容易让人混淆。它是指进程处于可运行的状态,或许正在运行,或许在就绪队列(也称为调度队列)中等待运行。因此Linux内核对当前正在运行的进程没有给出一个明确的状态,不像典型操作系统中给出两个很明确的状态,如就绪态和运行态。它是运行态和就绪态的一个集合,需要特别注意。
  • TASK_INTERRUPTIBLE (可中断睡眠态---S): 进程进入睡眠状态(被阻塞)来等待某些条件的达成或者某些资源的就位,一旦条件达成或者资源就位,内核就可以把进程的状态设置成TASK_RUNNING并将其加入就绪队列中。这个状态也称为浅睡眠状态。
  • TASK_UNINTERRUPTIBLE (不可中断态---D):这个状态和上面的TASK _NTERRUPTIBLE状态类似,唯一不同的是,进程在睡眠等待时不受干扰,对信号不做任何反应,所以这个状态称为不可中断态。通常使用ps命令看到的被标记为D状态的进程,就是处于不可中断态的进程,不可以发送SIGKILL信号使它们终止,因为它们不响应信号。这个状态也称为深度睡眠状态。
  • _ TASK_STOPPED (终止态---X): 进程停止运行。
  • EXIT_ZOMBIE (僵尸态---Z): 进程已经消亡,但是task_struct 数据结构还没有释放,这个状态叫作僵尸态,每个进程在它的生命周期中都要经历这个状态。子进程退出时,父进程可以通过wait()或者waitpid()来获取子进程消亡的原因。

上述5种状态在某种条件下是可以相互转换的。也就是说,进程可以从一状态转换到另一种状态, 如进程在等待某些条件或者资源时从可运行态转换到可中断睡眠状态。

僵尸进程、孤儿进程

一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。 所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程就会进入僵尸状态。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{printf("I am running...\n");pid_t id = fork();if(id == 0){ //childint count = 5;while(count){printf("I am child...PID:%d, PPID:%d, count:%d\n", getpid(), getppid(), count);sleep(1);count--;}printf("child quit...\n");exit(1);}else if(id > 0){ //fatherwhile(1){printf("I am father...PID:%d, PPID:%d\n", getpid(), getppid());sleep(1);}}else{ //fork error}return 0;
} 

 运行该代码后,我们可以通过以下监控脚本,每隔一秒对该进程的信息进行检测。

while :; do ps axj | head -1 && ps axj | grep proc | grep -v grep;echo "----------";sleep 1;done

 僵尸进程危害

 进程的退出状态必须被维持下去,因为他要告诉父进程,你交给我的任务,我办的怎么样了。可父进程如果一直不读取,那子进程就一直处于Z状态。维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,Z状态一直不退出,PCB一直都要维护。如果一个父进程创建了很多子进程,就是不回收,就会造成内存资源的浪费。因为数据结构对象本身就要占用内存,C中定义一个结构体变量(对象),是要在内存的某个位置进行开辟空间。僵尸进程会产生资源泄露。

孤儿进程:子进程先于父进程退出,运行在后台,父进程成为1号进程,退出后由1号进程回收资源,直接释放所有资源。

孤儿进程的产生一般都会带有目的性,比如我们需要一个程序运行在后台,或者我们不想一个进程退出后成为僵尸进程之类的需要。

写时拷贝技术

在传统的UNIX操作系统中,创建新进程时会拷贝父进程所拥有的所有资源,这样进程的创建变得很低效。每次创建子进程时都要把父进程的进程地址空间中的内容拷贝到子进程,但是子进程还不一定全盘接收,甚至完全不用父进程的资源。子进程调用execve()系统调用之后可能和父进程分道扬镳。

现代的操作系统都采用写时复制(Copy On Write, COW)的技术进行优化。写时拷贝就是父进程在创建子进程时不需要拷贝进程地址空间的内容到子进程,只需要拷贝父进程的进程地址空间的页表到子进程,这样父、子进程就共享了相同的物理内存。当父、子进程中有一方需要修改某个物理页面的内容时,触发写保护的缺页异常,然后才拷贝共享页面的内容,从而让父、子进程拥有各自的副本。也就是说,进程地址空间以只读的方式共享,当需要写入时才发生拷贝。写时复制是一种可以推迟甚至避免拷贝数据的技术,它在现代操作系统中有广泛的应用。

在采用了写时复制技术的Linux内核中,用frk0函数创建一个新进程的开销变得很小,免去了拷贝父进程整个进程地址空间中的内容的巨大开销,现在只需要拷贝父进程贯我的一点开销。

 

 

fork()函数

fork()是POSIX标准中定义的基本的进程创建函数。

使用fork()函数来创建子进程时,子进程和父进程有各自独立的进程地址空间,但是共享物理内存资源,包括进程上下文、进程堆栈、内存信息、打开的文件描述符、进程优先级、根目录、资源限制、控制终端等。在fork()创建期间,子进程和父进程共享物理内存空间,当它们开始执行各自程序时,它们的进程地址空间开始分道扬镳,这得益于写时复制技术。

子进程和父进程也有如下一些区别。

  • 子进程和父进程的ID不一样。子进程不会继承父进程的内存方面的锁,如mlock()。
  • 子进程不会继承父进程的一些定时器,如setitimer()、alarm()、 timer_create()。
  • 子进程不会继承父进程的信号量,如semop()。

对于fork()函数,在用户空间中的C库函数的定义如下。

#include <unistd.h>
#include <sys/types.h>


pid_ t  fork(void) ;

fork()函数会有两次返回,一次在父进程中,另一次在子进程中。如果返回值为0,说明这是子进程;如果返回值为正数,说明这是父进程,父进程会返回子进程的ID;如果返回一1,表示创建失败。


fork()函数通过系统调用进入Linux内核,然后通过do_ fork()函数来实现。

SYSCALL_DEFINEO (fork)

{
        return   _ do_ fork (SIGCHLD, 0,0, NULL, NULL, 0) ;
}

fork()函数只使用SIGCHLD标志位,在子进程终止后发送SIGCHLD信号通知父进程。fork()是重量级调用,为子进程建立了一个基于父进程的完整副本,然后子进程基于此执行。为了减少工作量,子进程采用写时拷贝技术,只拷贝父进程的页表,不会复制页面内容。当子进程需要写入新内容时才触发写时拷贝机制,并为子进程创建一个副本。
fork()函数也有一些缺点, 尽管使用了写时拷贝机制技术,但是它还需要拷贝父进程的页表,在某些场景下会比较慢,所以有了后来的vfork)和clone()。 

vfork()函数

vfork()函数和fork(函数类似,但是vfork()的父进程会一直阻塞, 直到子进程调用exit()或者execve()为止。在fork()实现写时拷贝之前,fork()之后马上执行execve()会造成的地址空间浪费和效率低下,因此设计了vfork()系统调用。

#include <sys/types.h>
#include <unistd.h>


 pid t vfork(void) ;

vfork()函数通过系统调用进入Linux内核,然后通过do_ fork()函 数来实现。
 

SYSCALL DEFINEO (vfork)

{

        return  _do_ fork (CLONE_ VFORK   |  CLONE_VM   |  SIGCHLD,0,                                        0, NULL, NULL, 0) ;

}

 vfork(的实现比fork()的实现多了两个标志位,分别是CI ONE_VFORK和CLONE_VM。CLONE_VFORK表示父进程会被挂起,直至子进程释放虚拟内存资源。CLONE_VM表示父、子进程执行在相同的进程地址空间中。另外,通过vfork()可以避免拷贝父进程的页表项。

终止进程

系统中有源源不断的进程诞生,当然,也有进程会终止。进程的终止有两种方式:一种是自愿地终止,包括显式地调用exit()系统调用或者从某个程序的主函数返回;另一种是被动地收到终止信号或者异常终止。

进程主动终止主要有如下两个途径。

  • 从main()函数返回,链接程序会自动添加exit()系统调用。
  • 主动调用 exit系统调用。

进程被动终止主要有如下3个途径。

  • 进程收到一个自己不能处理的信号。
  • 进程在内核态执行时产生 了一个异常。
  • 进程收到 SIGKILL等终止信号。


当一个进程终止时,Linux 内核会释放它所占有的资源,并把这个消息告知父进程,而个进程终止时可能有两种情况。

  • 若它先于父进程终止,那么子进程会变成一个僵尸进程,直到父进程调用wait()才算最终消亡。
  • 若它也在父进程之后终止, 那么init 进程将成为子进程的新父进程。

kill 命令是通过向进程发送指定的信号来结束进程的,基本用法为

kill [-s,--信号 | -p] [-a] 进程号...

选项-s指定需要送出的信号,既可以是信号名也可以是对应数字。默认为TERM信号(值15)。

选项-p指定kill命令只是显示进程的pid,并不真正送出结束信号。

信号SIGKILL (值为9)用于强行结束指定进程的运行,适合于结束已经挂死而没有能力自动结束的进程,这属于非正常结束进程。

假设某进程(PID为3456 )占用过多CPU资源,使用命令kill 3456并没有结束该进程,这就需要执行命令kill -9 3456强行将其终止。

Linux下还提供一个kll命令,能直接使用进程的名字而不是进程号作为参数,例如:

killall xineta

如果系统存在同名的多个进程,则这些进程将全部结束运行。 

进程优先级和权重

操作系统中经典的进程调度算法是基于优先级调度的。优先级调度的核心思想是把进程按照优先级进行分类,紧急的进程优先级高,不紧急、不重要的进程优先级低。调度器总是从就绪队列中选择优先级高的进程进行调度,而且优先级高的进程分配的时间片会比优先级低的进程长,这体现了一种等级制度。
Linux操作系统最早采用nice值来调整进程的优先级。nice值的思想是要对其他进程友好,降低优先级来支持其他进程消耗更多的处理器时间。它的范围-20~+19,默认值是0。nice值越大,优先级反而越低;nice值越低,优先级越高。nice 值-20表示这个进程是非常重要的,优先级最高;而nice值19则表示允许其他进程比这个线程优先享有宝贵的CPU时间,这也是nice值的由来。

内核使用0~ 139的数值表示进程的优先级,数值越小,优先级越高。优先级0~99给给实时进程使用,100~139 给普通进程使用。另外,在用户空间中有一个传统的变量nice,它用于映射普通进程的优先级,即100~ 139。

优先级在Linux内核中的划分方式如下。

  • 普通进程的优先级: 100~ 139。
  • 实时进程的优先级: 0~99。
  • deadline进程的优先级: - 1。

进程地址空间

进程地址空间是指进程可寻址的虚拟地址空间。在64位系统的处理器中,进程可以寻址256TB的用户态地址空间,但是进程没有权限去寻址内核空间的虚拟地址,只能通过系统调用的方式间接访问。而用户空间的进程地址空间则可以被合法访间,地址空间称为内存区域。进程可以通过内核的内存管理机制动态地添加和删除这些内存区域,这些内存区域在Linux内核采用VMA数据结构来抽象描述。

每个内存区域具有相关的权限,如可读、可写或者可执行权限。若一个进程访问了不在有效范围的内存区域,或者非法访问了内存区域,或者以不正确的方式访问了内存区域,那么处理器会报告缺页异常。在Linux内核的缺页异常处理中会处理这些情况,严重的会报告“SegmentFault”并终止该进程。

内存区域包含内容如下:

  • 代码段映射,可执行文件中包含只读并可执行的程序头,如代码段和init段等。
  • 数据段映射,可执行文件中包含可读/可写的程序头,如数据段和未初始化数据段等。
  • 用户进程栈。通常位于用户空间的最高地址,从上往下延伸。它包含栈帧,里面包含了局部变量和函数调用参数等。注意,不要和内核栈混淆,进程的内核栈独立存在并由内核维护,主要用于上下文切换。
  • mmap映射区域。位于用户进程栈下面,主要用于mmap系统调用,如映射一个文件的内容到进程地址空间等。
  • 堆映射区域。malloc()函数分配的进程虚拟地址就是这段区域。


进程地址空间里的每个内存区域相互不能重叠。如果两个进程都使用malloc()函数来分配内存,分配的虚拟内存的地址是一样的,那是不是说明这两个内存区域重叠了呢?

如果理解了进程地址空间的本质就不难回答这个问题了。进程地址空间是每个进程可以寻址的虚拟地址空间,每个进程在执行时都仿佛拥有了整个CPU资源,这就是所谓的“CPU虚拟化”。因此,每个进程都有一套页表,这样每个进程地址空间就是相互隔离的。即使它们的进程地址空间的虚拟地址是相同的,但是经过两套不同页表的转换之后,它们也会对应不同的物理地址。

 mm_struct 数据结构
Linux内核需要管理每个进程所有的内存区域以及它们对应的页表映射,所以必须拍象出一个数据结结构,这就是mm_ struct数据结构。进程控制块( PCB)——数据结构task_struct中有一个指针mm,该指针指向这个task_struct数据结构。

http://www.zhongyajixie.com/news/31287.html

相关文章:

  • 小规模企业做网站网站优化网站优化
  • 网站备案密码重置申请表小程序推广运营的公司
  • 网站开发和网站建设免费网络营销方式
  • 济南做网站找大标seo搜索引擎优化试题及答案
  • 建设网站建设多少钱网站排名优化怎样做
  • 一个ip地址上可以做几个网站互联网营销工具有哪些
  • 企业定制网站建设公司关键词优化的作用
  • 哪个网站可以接针织衫做单百度文库首页官网
  • wordpress标题字体太大西安网站排名优化培训
  • 装修公司怎么做免费网站河源今日头条新闻最新
  • 电子商务网站设计心得google下载手机版
  • 如何做跨境购物网站关键词挖掘工具爱网
  • 网站开发技术方案编写谈谈对seo的理解
  • 网站如何设置微信支付功能站长工具a级
  • 销售易crm收费标准网站标题seo外包优化
  • 兰溪做网站哪家好爱站网seo综合查询工具
  • 简单大气网站杭州网站优化方案
  • 网站seo怎样做百度游戏中心官网
  • 做招聘网站的需求分析广东网络推广运营
  • 网站美工的重要性百度视频下载
  • 做网站准备seo网站推广报价
  • 快餐小吃加盟方案郑州关键词优化费用
  • 云建站源码百度成都总部
  • 阳谷网站建设网络推广什么是交换链接
  • wordpress 8m限制新区seo整站优化公司
  • 怎么做网站开始动画如何建立自己的网站平台
  • wordpress百度mlpseo整站优化更能准确获得客户
  • 做网站合同模板厦门seo
  • wordpress热门插件安卓优化软件
  • 网页开发和网站开发一样吗线上如何做推广