LINUX进程编程

上传人:油条 文档编号:47637868 上传时间:2018-07-03 格式:PPT 页数:49 大小:353.50KB
返回 下载 相关 举报
LINUX进程编程_第1页
第1页 / 共49页
LINUX进程编程_第2页
第2页 / 共49页
LINUX进程编程_第3页
第3页 / 共49页
LINUX进程编程_第4页
第4页 / 共49页
LINUX进程编程_第5页
第5页 / 共49页
点击查看更多>>
资源描述

《LINUX进程编程》由会员分享,可在线阅读,更多相关《LINUX进程编程(49页珍藏版)》请在金锄头文库上搜索。

1、Linux进程编程授课老师:张涛 进程 P242在操作系统中,各个程序之间是并发执行 的,共享系统资源。CPU需要在各个运行的 程序之间来回地切换,这样的话,要想描述 这些并发活动过程就变得很困难。为此,操 作系统设计者提出了进程的概念。什么是进程? P242A process a program in execution 一个进程应该包括:程序的代码;程序的数据;PC中的值,用来指示下一条将运行的指令;一组通用的寄存器的当前值,堆、栈;一组系统资源(如打开的文件)总之,进程包含了正在运行的一个程序的所有 状态信息。进程状态的转换 P242 时间片轮转调度算法 P242 在时间片轮转算法中,将

2、所有的就绪任务按照FCFS (First Come First Served)原则,排成一个队列; 每次调度时将处理器分派给队首任务,让其执行一小段CPU时间(时间片,time slice); 在一个时间片结束时,如果任务还没有执行完的话,将发生时钟中断,在时钟中断中,调度程序将暂停当前任务的执行,并将其送到就绪队列的末尾,然后执行当前的队首任务;开始时,任务B位于队列之首,因此被调度执行。当 它的时间片用完后,就把它送到就绪队列的末尾。 同时,任务F成为新的队首,被调度运行。抢占调度方式 P242任务1 任务2 任务1 优先级 高低时间 任务2 任务3 表示抢占 表示结束 实际上创建进程就是

3、给任务代码分配一个 任务控制块。task_struct中有一个指针指向 files_struct结构体,称为文件描述符表,其中 每个表项包含一个指向已打开的文件的指针 typedef struct os_tcb OS_STK *OSTCBStkPtr; struct os_tcb *OSTCBNext; INT16U ID; 进程IDINT8U OSTCBPrio; 进程优先级file struct OS_TCB; 任务等待的延迟时间(节拍数)任务控制块 P242文件描述符表 P242用户程序不能直接访问内核中的文件描述符表,而只能使用文件 描述符表的索引(即0、1、2、3这些数字),这些索引

4、就称为文 件描述符(File Descriptor),用int型变量保存。当调用open打 开一个文件或创建一个新文件时,内核分配一个文件描述符并返 回给用户程序,该文件描述符表项中的指针指向新打开的文件。 当读写文件时,用户程序把文件描述符传给read或write,内核根 据文件描述符找到相应的表项,再通过表项中的指针找到相应的 文件。 进程与进程ID P245程序被执行的实例被称为进程,进程空间包括(代码空间、数 据空间、运行的堆栈空间)存在与内存中。 程序是静态的,存放在硬盘上,是永久的。进程是动态的,是 暂时的,有其生命周期的。 操作系统为其分配好进程的空间时,从main函数开始运行时

5、标 志着进程的开始,当调用exit函数退出时标志着进程的结束。 每个LINUX进程都有一个唯一的ID,进程ID总是一个非负数。 getpid() getppid() 进程的控制: fork、exec、waitpid。 1、用户ID getuid() 2、组ID getgid()用户标识 P247出错处理 P247 当LINUX函数出错时,会给整型变量errno设置一个 值,errno每一个值都有特定含义。 strerror(i) 将函数映射为一个出错信息字符串。 perror (const char msg) 在标准出错上产生一条出错信息(基于errno)Linux 信号量 ? P249信号量

6、本质上是一个非负的整数计数器,它被用来控制对公共 资源的访问。 当公共资源增加时,调用函数sem_post()增加信号量。 只有当信号量值大于时,才能使用公共资源,使用后,函数 sem_wait()减少信号量。Linux 信号量 ? P2491、忽略该信号。 2、按系统默认方式处理。 3、提供一个函数,信号发生时则调用该函数。Linux 时间值1、日历时间 2、进程时间。时钟时间、用户CPU时间、系统CPU时间。 $time ./test real 0m0.06s user 0m0.01s Sys 0m0.00s系统调用和库函数 ? P2501、系统调用:系统调用把应用程序请求传给内核,调用相

7、应的 内核函数完成所需的处理。使应用程序由用户态进入核心态,系 统调用有自己单独的堆栈空间。 2、库函数:存放在函数库中的函数,库函数具有明确的功能、 入口调用参数和返回值,Linux库函数特指函数入口没有进行系 统调用的库函数。库函数中常包含系统调用,库函数没有进行系 统调用时,没有单独的堆栈空间。 printfwrite strcpy atoi用户空间系统调用库函数库函数用户代码内核系统空间用户进程3、用户态:进程的普通执行状态,只能执行规定的指令,不 能执行特权指令。进程在用户态下只能访问该进程的存储空间 ,不能与系统硬件相互作用,不能访问系统资源,当它需要系 统硬件资源时,会通过系统调

8、用进入核心态。 4、核心态:能执行所有的机器指令,包括操作系统执行的特 权指令,能访问所有的寄存器和存储区域,能直接控制所有系 统资源和硬件资源。Linux 进程环境 P2561、Linux进程控制块(PCB)的作用? Linux进程控制块是一个由结构体task_struct所定义的数据结构 操作系统利用PCB来控制和管理进程。地址tasknexttasknexttasknext等待态 任务结构体等待态 任务结构体等待态 任务结构体Linux进程等待列图2、与进程有关的ID P257 进程真实用户号(UID) getuid() 有效用户号(EUID) geteuid() 真实用户组号(GID)

9、 getgid() 有效用户组号(EGID) getegid() 进程标识号(PID) getpid() 进程组标识号(PGID) getpgid()linux系统中每个进程都有2个ID,分别为用户ID和有效用户ID ,UID一般表示进程的创建者(属于哪个用户创建),而EUID 表示进程对于文件和资源的访问权限(具备等同于哪个用户的 权限)。可以通过函数getuid()和geteuid()获得进程的两个 ID值。 一般情况下2个ID是相同的,但是某些情况下会出现2个ID不 同的情况。进程终止 P2581、正常终止 1)从main返回 2)调用exit。 3)调用_exit。 2、异常终止 1)

10、调用abort 2)由一个信号终止。exit与return的区别 ?C语言关键字与函数exit()在main函数退出时有相似之处,但两 者有本质的区别: return 退出当前函数主体,exit()函数退出当前进程,因此,在 main函数里面return(0)和exit(0)完成一样的功能。 return仅仅从子函数中返回,而子进程用exit()退出,调用exit() 时要调用一段终止处理程序,然后关闭所有I/O流。exit()与_exit() ? P258都是用来终止进程的。 _exit() 直接使进程停止进行,清除其使用的内存空间,并清除 其在内核中的各种数据结构。 exit()函数在退出

11、前检查文件的打开情况,把文件缓存中的内容 写进文件。 exit() _exit() atexit()得到进程结束标志 通过执行码 $echo $?得到已结束进程的结束状态。 1、程序中main函数运行结束,$?中保存main函数的返回值 。 2、程序运行中调用exit函数结束运行,$?中保存exit函数参 数。 3、程序异常退出,$?中保存异常出错的错误号。进程的堆栈空间 P262(1)代码区(text segment)。加载的是可执行文件代码段,其加 载到内存中的位置由加载器完成。 (2)全局初始化数据区/静态数据区(Data Segment)。加载的是 可执行文件数据段,存储于数据段(全局

12、初始化,静态初始化数据 )的数据的生存周期为整个程序运行过程。int count=30; (3)未初始化数据区(BSS)。存储于数据段的数据(全局未初始 化,全局静态,局部静态未初始化数据)的生存周期为整个程序运 行过程。long sum1000; (4)栈区(stack)。由编译器自动分配释放,存放函数的参数值、 返回值、局部变量等。在程序运行过程中实时加载和释放,因此, 局部变量的生存周期为申请到释放该段栈空间。 (5)堆区(heap)。用于动态内存分配。堆在内存中位于BSS区和 栈区之间。一般由程序员分配和释放,若程序员不释放,程序结束 时有可能由OS回收。malloc,calloc,r

13、ealloc函数。12.3 Linux进程控制 P2671、进程标识 每个进程都有一个非负整型的唯一进程ID。 ID 0 调度进程,不执行任何磁盘上的程序,是内核的一部分。 ID 1 init进程,读与系统有关的初始化文件,并将系统引导到 一个状态,绝不会终止,是一个普通用户进程,是所有孤儿进 程的父进程。fork 系统调用 ? P269-270fork从已存在的进程中创建一个新进程,新进程成为子进程, 原进程为父进程。 fork调用一次,返回两次,在父进程中返回为子进程的进程号 ,在子进程中返回为0。 使用fork函数得到了父进程的一个复制品,从父进程处继承了 整个进程的地址空间,子进程独有

14、的只是它的地址号。 fork复制了父进程中数据段和堆栈段中绝大部分内容,使的 fork系统调用的执行速度并不快。 fork 所有由父进程打开的文件描述符都被复制到子进程中。父 子进程有相同编号的文件描述符fork 系统调用时完成的操作 ? P2701、为新进程分配task_struct任务结构体内存空间。 2、把父进程task_struct任务结构体复制到子进程task_struct。 3、为新进程建立内核堆栈。 4、对子进程task_struct任务结构体中部分变量进行初始化设置。 5、把父进程有关信息复制给子进程,建立共享关系。 6、把子进程加入到可运行队列。 7、结束fork()函数, 8、当子进程开始时,操作系统返回0给子进程中栈段变量id。P

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号