帮助文档
专业提供香港服务器、香港云服务器、香港高防服务器租用、香港云主机、台湾服务器、美国服务器、美国云服务器vps租用、韩国高防服务器租用、新加坡服务器、日本服务器租用 一站式全球网络解决方案提供商!专业运营维护IDC数据中心,提供高质量的服务器托管,服务器机房租用,服务器机柜租用,IDC机房机柜租用等服务,稳定、安全、高性能的云端计算服务,实时满足您的多样性业务需求。 香港大带宽稳定可靠,高级工程师提供基于服务器硬件、操作系统、网络、应用环境、安全的免费技术支持。
服务器资讯 / 香港服务器租用 / 香港VPS租用 / 香港云服务器 / 美国服务器租用 / 台湾服务器租用 / 日本服务器租用 / 官方公告 / 帮助文档
Linux——进程概念(上)
发布时间:2024-03-06 13:38:10   分类:帮助文档
Linux——进程概念(上) 文章目录 1. 冯诺依曼体系结构2. 操作系统(Operator System)2.1 概念2.2 设计OS的目的2.3 如何理解 "管理"2.4 总结2.5 系统调用和库函数概念 3. 进程3.1 描述进程-PCB3.2 task_ struct内容分类3.3 组织进程3.4 查看进程3.5 杀掉进程 4. 通过系统调用获取进程标示符5. 通过系统调用创建进程-fork初识5.1 pid_t fork()5.2 fork的基本用法 6. linux操作系统的进程状态6.1 理论状态6.2 具体状态:6.3 进程状态查看 7. Z(zombie)-僵尸进程7.1僵尸进程危害 8. 孤儿进程9.进程优先级9.1 基本概念9.2 查看系统进程9.3 PRI and NI9.4 PRI vs NI9.5 查看进程优先级的命令 10. 其他概念 1. 冯诺依曼体系结构 截至目前,我们所认识的计算机,都是有一个个的硬件组件组成 输入单元(设备):包括键盘, 鼠标,扫描仪, 写板,磁盘,摄像头,话筒,网卡等中央处理器(CPU):含有运算器(算术运算,逻辑运算)和控制器(CPU是可以响应外部事件的,协调外部就绪事件,例如拷贝数据到内存)等输出单元(设备):显示器,打印机,音响,磁盘,网卡等     关于冯诺依曼,必须强调几点: 这里的存储器指的是内存不考虑缓存情况,这里的CPU能且只能对内存进行读写,不能访问外设(输入或输出设备)外设(输入或输出设备)要输入或者输出数据,也只能写入内存或者从内存中读取。一句话,所有设备都只能直接和内存打交道   CPU读取数据(数据+代码)都是要从内存中读取的。站在数据的角度,我们认为CPU不和外设直接交互CPU要处理数据,需要先将外设中的数据加载到内存。站在数据的角度,外设直接和内存打交道     2. 操作系统(Operator System) 2.1 概念 任何计算机系统都包含一个基本的程序集合,称为操作系统(OS)。 笼统的理解,操作系统包括: 内核(进程管理,内存管理,文件管理,驱动管理)其他程序(例如函数库, shell程序等等)   2.2 设计OS的目的 与硬件交互,管理所有的软硬件资源为用户程序(应用程序)提供一个良好的执行环境定位 在整个计算机软硬件架构中,操作系统的定位是: 一款纯正的“搞管理”的软件 2.3 如何理解 “管理” 管理是对被管理对象的数据管理 管理理念:先描述,再组织 例如:先对被管理对象进行描述,再根据描述类型,定义对象,可以把对象组织成数组——>对学生的管理工作就变成了对数组的增删查改 Linux内核是用C语言写的struct OS:内部,一定存在大量的数据结构和算法 2.4 总结 计算机管理硬件: 描述起来,用struct结构体组织起来,用链表或其他高效的数据结构   2.5 系统调用和库函数概念 在开发角度,操作系统对外会表现为一个整体,但是会暴露自己的部分接口,供上层开发使用,这部分由操作系统提供的接口,叫做系统调用。  系统调用在使用上,功能比较基础,对用户的要求相对也比较高,所以,有心的开发者可以对部分系统调用进行适度封装,从而形成库,有了库,就很有利于更上层用户或者开发者进行二次开发。     3. 进程 我们自己启动一个软件,本质其实就是启动了一个进程 在linux下,运行一条命令,其实就是在系统层面创建了一个进程 linux是可以同时加载多个程序的,linux是肯同时存在大量的进程在系统中(OS,内存)所以必须管理进程 先描述,再组织 进程 = 对应的代码和数据 + 进程对应的PCB结构体 3.1 描述进程-PCB PCB process control block 本质是一个结构体struct 不同的操作系统中,PCB的名字不一样 Linux:struct task_struct .exe可执行程序其实本质就是文件:代码+数据 人认识世界,是通过属性来认识的 属性也是数据 文件 = 内容+属性 PCB包含了所有进程属性(struct) 对进程的管理,变成了对进程PCB结构图链表的增删查改 PCB是新增的 3.2 task_ struct内容分类 标示符: 描述本进程的唯一标示符,用来区别其他进程。状态: 任务状态,退出代码,退出信号等。优先级: 相对于其他进程的优先级。程序计数器: 程序中即将被执行的下一条指令的地址。内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。I/ O状态信息: 包括显示的I/O请求,分配给进程的I/ O设备和被进程使用的文件列表。记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。其他信息 3.3 组织进程 可以在内核源代码里找到它。所有运行在系统里的进程都以task_struct链表的形式存在内核里。   3.4 查看进程 ps ps axj ps axj | greap ‘myproc’ ps axj | head -1 && ps axj | greap ‘myproc’ top ls /proc 里面的文件是动态的 cwd是当前进程的工作目录,一般都是默认打开当前路径     3.5 杀掉进程 kill -9 id     4. 通过系统调用获取进程标示符 进程id(PID)父进程id(PPID)永远都是bash #include #include #include int main() { while(1) { pid_t id = getpid();//获取的是自己的进程PID printf("hello world,pid:%d,ppid:%d\n",id,getppid()); sleep(1); } }     5. 通过系统调用创建进程-fork初识 5.1 pid_t fork() 运行 man fork 认识forkfork有两个返回值父子进程代码共享,数据各自开辟空间,私有一份(采用写时拷贝) 返回值: 失败的时候,返回-1成功的时候: 给父进程返回子进程的pid给子进程返回0   5.2 fork的基本用法 fork之后,代码是父子共享的 先写出程序对应的Makefile 一下代码的执行情况是打印了两次you can see me !   fork之后有两个不同的执行流 int main() { pid_t id = fork(); if(id < 0) { //创建失败 perror ("fork"); return 1; } else if(id == 0) { //child process(task) while(1) { printf("I am child,pid: %d,ppid: %d\n",getpid(),getppid()); sleep(1); } } else { //parent process while(1) { printf("I am father,pid: %d,ppid: %d\n",getpid(),getppid()); sleep(1); } } return 0; }   以下有几个关于frok的问题: 为什么给子进程返回0,给父进程返回子进程的pid? 比例,父进程:子进程=1:n 所以父进程唯一,子进程可以有许多个,为了区分所以需要返回子进程的pid 为什么有两个返回值? 因为fork内部父子会各自执行自己的return语句 返回两次并不意味着保留两次 3 创建进程的时候,OS要做什么? 要先新建一个task_struct 当我们以及准备return了,我们的核心代码执行完了吗? 已经完成了 操作系统和CPU运行某一个进程,本质是从task_struct形成的队列中挑选一个task_struct,来执行它的代码 进程调度就变成了task_struct的队列中选择一个进程的过程 只要想到进程,优先想到进程对应的task_struct 父子进程被创建出来,哪一个会先被执行呢? 不一定 是由操作系统的调度器决定的   6. linux操作系统的进程状态 6.1 理论状态   新建:字面意思运行:task_struct结构体在运行队列中排队,就叫做运行态阻塞:等待非CPU资源就绪,阻塞状态 系统中一定是存在各种资源的(不仅仅是CPU),网卡,磁盘,显卡等等其他设备,所以系统中不只是只存在一种队列 挂起:内存快不足的时候,操作系统会将长时间不执行的进程代码和数据换出到磁盘(swap)此时这个进程在内存中只有PCB,此时进程的状态就叫做挂起退出:字面意思 进程可以分为前台进程和后台进程(&) ./myproc ./myproc &   6.2 具体状态: R 运行状态(running) : 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。S 睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠(interruptible sleep))D 磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。T 停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态。 当服务器压力过大时,os会通过一定的手段杀掉一些进程,来节省空间     6.3 进程状态查看 ps aux / ps axj 命令     7. Z(zombie)-僵尸进程 一个进程已经退出,但是还不允许被OS释放,处于一个被检测的状态 维持该状态是为了让父进程和OS来回收 僵死状态(Zombies)是一个比较特殊的状态。 当进程退出并且父进程(使用wait()系统调用) 没有读取到子进程退出的返回代码时就会产生僵死(尸)进程 僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。 所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态   7.1僵尸进程危害 进程的退出状态必须被维持下去,因为他要告诉关心它的进程(父进程),你交给我的任务,我办的怎么样了。 可父进程如果一直不读取,那子进程就一直处于Z状态。 维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话说, Z状态一直不退出, PCB就一直都要维护。 一个父进程创建了很多子进程,就是不回收,就会造成内存资源的浪费。 因为数据结构对象本身就要占用内存,想想C中定义一个结构体变量(对象),是要在内存的某个位置进行开辟空间! 也会发生内存泄漏 创建一个维持30s的僵尸进程: #include #include int main() { pid_t id = fork(); if(id < 0){ perror("fork"); return 1; } else if(id > 0){ //parent printf("parent[%d] is sleeping...\n", getpid()); sleep(30); }else{ printf("child[%d] is begin Z...\n", getpid()); sleep(5); exit(EXIT_SUCCESS); } return 0; }     8. 孤儿进程 父进程如果提前退出,那么子进程后退出,进入Z之后,那该如何处理呢? 父进程退出,子进程还在,子进程就叫做孤儿进程孤儿进程会被领养,被1号进程领养(init,系统本身) 为什么要被领养? 未来子进程退出的时候,父进程早已不在,需要领养进程来进行回收 写一个孤儿程序: #include #include int main() { pid_t id = fork(); if(id == 0) { //child while(1) { printf("hello wowo!\n"); sleep(1); } } else { //father int cnt = 5; while(cnt) { printf("I am father: %d\n",cnt--); sleep(1); } } return 0; } 运行程序之后,屏幕上打印五行I am father: cnt–(5,4,3,2,1) 之后就一直在打印hello wowo! 这里使用ctrl+c也无法终止程序 所以需要杀掉程序的命令 kill -9 id 先使用ps命令查看ID ps ajx I head -1 ps ajx | head -1 && ps axj | grep myproc ps ajx | head -1 && ps axj | grep myproc | grep -v grep while :; do ps ajx | head -1 && ps axj | grep myproc | grep -v grep; sleep 1; echo ""; done 如上图所示,输入命令 kill -9 69657 就可以杀掉(回收)程序了     9.进程优先级 为什么要有优先级? 本质原因就是因为CPU是有限的,而进程太多,所以需要通过某种方式竞争资源。 什么是优先级? 确认是谁应该先获得某种资源,谁后获得 (我们是可以用一些数据来表明优先级的) 调度性 优先级——调度指标 9.1 基本概念 cpu资源分配的先后顺序,就是指进程的优先(priority)。优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可以改善系统性能。还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能。     9.2 查看系统进程 linux具体的优先级做法: 1优先级 = 老的优先级 + nice值 老的优先级都是80,每次设置优先级,都要从进程最开始的优先级开始设置 在linux或者unix系统中,用ps –l命令则会类似输出以下几个内容: UID : 代表执行者的身份PID : 代表这个进程的代号PPID :代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号PRI :代表这个进程可被执行的优先级,其值越小越早被执行NI :代表这个进程的nice值   9.3 PRI and NI PRI,即进程的优先级,或者通俗点说就是程序被CPU执行的先后顺序,此值越小进程的优先级别越高 NI,就是nice值,其表示进程可被执行的优先级的修正数值 PRI值越小越快被执行,那么加入nice值后,将会使得PRI变为:PRI(new)=PRI(old)+nice 当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行 调整进程优先级,在Linux下,就是调整进程nice值 nice其取值范围是-20至19,一共40个级别。     9.4 PRI vs NI 需要强调一点的是,进程的nice值不是进程的优先级,他们不是一个概念,但是进程nice值会影响到进程的优先级变化。 可以理解nice值是进程优先级的修正修正数据 9.5 查看进程优先级的命令 while :; do ps -al | head -1 && ps -la | greap myproc; sleep 1; done 用top命令更改已存在进程的nice: 输入top 进入top后按“r” PID to renic [default pid = 1491] 输入进程PID, PID to renic [default pid = 1491] 17417 之后回车 Renic Pid 17417 to value 输入nice值 Renic Pid 17417 to value 20     10. 其他概念 竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发 CPU调度代码 时间片 抢占与出让 切换: CPU会存在大量的寄存器 如果进程A正在运行,CPU内的寄存器里面,一定保存的是进程A的临时数据 寄存器中的临时数据叫做A的上下文 上下文的数据可以被丢弃吗?绝对不可以!! 当进程A暂时被切下来的时候,需要进程A顺便带走自己的上下文数据 带走暂时保存的目的:就是为了下次回来的时候,能恢复上去,就能按照之前的逻辑继续向后运行,就如同没有中断过一样。 cpu内的寄存器只有一份,但是上下文可以有多份,分别对应不同的进程
香港云服务器租用推荐
服务器租用资讯
·广东云服务有限公司怎么样
·广东云服务器怎么样
·广东锐讯网络有限公司怎么样
·广东佛山的蜗牛怎么那么大
·广东单位电话主机号怎么填写
·管家婆 花生壳怎么用
·官网域名过期要怎么办
·官网邮箱一般怎么命名
·官网网站被篡改怎么办
服务器租用推荐
·美国服务器租用
·台湾服务器租用
·香港云服务器租用
·香港裸金属服务器
·香港高防服务器租用
·香港服务器租用特价