《Linux应用开发 之 进程编程基础.pdf》由会员分享,可在线阅读,更多相关《Linux应用开发 之 进程编程基础.pdf(25页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、中标中标中标中标 LinuxLinuxLinuxLinux 系列讲座系列讲座系列讲座系列讲座中标软件有限公司 中标软件有限公司 2011/09LinuxLinuxLinuxLinux 应用开发 应用开发 应用开发 应用开发 进程编程基础进程编程基础进程编程基础进程编程基础Linux 开发 进程编程基础进程介绍进程介绍进程编程基础进程编程基础进程创建进程创建进程执行进程执行进程等待进程等待进程退出进程退出进程属性进程属性 进程是一个程序的一次执行过程,它是操作系统的基本调度单位。一个进程由以下组成:进程上下文,表示进程执行的状态;程序当前的执行目录;程序服务的文件和目录;程序的访问权限;内存和其
2、他分配给进程的系统资源;Linux 下每个进程用唯一的进程号(PID)来标识。进程最主要的属性就是进程号和父进程号。Linux 系统内所有进程为树形结构关系。PID 为 1 的 init 进程是根节点。使用 pstree 命令,查看系统内正在执行的各个进程间的继承关系。Linux 系统包括 3 种类型的进程:交互进程:由 shell 启动,可在前台或后台运行。批处理进程:与终端没有联系,是一个进程序列。监控进程:又称守护进程,在后台运行。进程编程基础 进程介绍进程状态进程状态 进程模型中存在如下各种状态:用户状态:在用户态环境下运行;内核状态:在内核态环境下运行;内存中就绪:没有执行,但处于就
3、绪状态。只要内核调度,就可执行;内存中睡眠:正在睡眠且存储在内存中,没有被交换到 SWAP 设备中;就绪且换出:处于就绪状态,但需要换入内存,内核才能再次调度它;睡眠且换出:正在睡眠,且被换出内存;被抢先:从内核态返回用户态时,内核抢先调度了另外一个进程;创建状态:刚被创建时,是最初的状态;僵死状态:调用 exit 结束,进程不再存在,但进程表项中有记录;进程编程基础 进程介绍进程结构进程结构 Linux 系统中,一个进程在内存里由 3 部分数据组成:代码段:存放程序代码的数据;多个进程运行同一个程序,共用一个代码段;数据段:存放程序的全局变量、常量及动态数据分配的数据空间;堆栈段:存放的是子
4、程序的参数、返回地址及局部变量;系统在收到中断、执行系统调用或内核做上下文切换时,会保存进程上下文,其包括:该进程用户空间内容、寄存器内容及相关的内核数据结构。内核在以下几种情况下允许发生上下文切换:进程自身进入睡眠时;进程执行完系统调用要返回用户态,但发现该进程不是最具资格运行的进程时;内核完成中断处理后要返回用户态,但发现该进程不是最有资格运行的进程时;进程退出时;进程编程基础 进程介绍进程控制进程控制 在 Linux 系统中,使用系统调用 fork 来创建进程。内核为完成 fork 调用会进行如下操作:在进程表中为新进程分配表项;给子进程分配唯一的进程标识号,也就是进程表中的索引号;复制
5、父进程的进程表项给子进程;具有与父进程一样的 uid、euid、gid 等;把与父进程相连的文件表和索引节点表的引用数加 1;内核为子进程创建用户级上下文;生成进程的动态部分,内核复制父进程的上下文的寄存器上下文和内核栈,调用对父进程返回子进程的进程标识号,对子进程返回 0;Linux 系统调用 exit 用来终止进程执行。内核会释放进程所占资源和内存空间,保留进程表项,并设置为僵死状态。Linux 系统调用 wait 用来和子进程同步。如果没有子进程则返回错误;如果子进程僵死则返回进程标识号及退出时给父进程的参数;如果子进程没有僵死,调用进程就阻塞了,等待子进程僵死或其他信号。Linux 系
6、统调用 exec 用来实现对其他程序的调用。进程编程基础 进程介绍Linux 开发 进程编程基础进程介绍进程介绍进程编程基础进程编程基础进程创建进程创建进程执行进程执行进程等待进程等待进程退出进程退出调用函数调用函数 创建进程的系统调用有:fork():创建的子进程复制父进程的资源,包括内存资源;vfork():创建的不是真正意义的进程,而是线程,其共享内存资源。由vfork 创造出来的子进程还会导致父进程挂起,除非子进程 exit 或者 execve 才会唤起父进程;clone():功能强大,支持很多参数,可类似 fork 或 vfork,甚至可以创建兄弟进程。Linux 系统中,系统调用
7、fork()、vfork()和 clone()都是通过调用内核函数来实现的。对应的内核函数分别是 sys_fork()、sys_vfork()和sys_clone()。内核中通过调用 do_fork()函数实现。do_fork()调用 copy_process()函数实现进程复制 copy_process()复制父进程的数据段和堆栈段,同时为子进程生成一个 PID。进程编程基础 进程创建调用函数(续)调用函数(续)fork()将程序分成两段。父进程执行整个程序,子进程只执行将程序分成两段。父进程执行整个程序,子进程只执行fork()调用之后的部分调用之后的部分。fork()调用一次,调用一次,
8、返回值两次,分别在父进程和子进程。返回值两次,分别在父进程和子进程。返回值返回值 00:代码执行在父进程中,返回值代表子进程的代码执行在父进程中,返回值代表子进程的 PIDPID=0 0:代码执行在子进程中代码执行在子进程中 00:只等待进程 ID 等于 pid 的子进程,不管其它已经有多少子进程运行结束退出了,只要指定的子进程还没有结束,waitpid 就会一直等下去;pid=-1:等待任何一个子进程退出,没有任何限制,此时 waitpid 和 wait 的作用一样;pid=0:等待同一个进程组中的任何子进程,如果子进程已经加入了别的进程组,则 waitpid 不会对它做任何理睬;pid-1
9、:等待一个指定进程组中的任何子进程,该进程组的 ID 等于 pid 的绝对值;参数参数 options WNOHANG:即使没有子进程退出,它也会立即返回,不会像 wait 那样永远等下去;WUNTRACED:子进程进入暂停则马上返回,但结束状态不予以理会;进程编程基础 进程执行waitpid 返回值返回值 正常退出,返回收集到的子进程的进程正常退出,返回收集到的子进程的进程 ID;如果设置了选项如果设置了选项 WNOHANG,而调用中而调用中 waitpid 发现没有已退出发现没有已退出的子进程可收集的子进程可收集,则返回则返回 0;如果调用中出错如果调用中出错,则返回则返回-1,这时这时
10、errno 会被设置成相应的值以指会被设置成相应的值以指示错误所在;示错误所在;例如:当 pid 所指示的子进程不存在,或此进程存在,但不是调用进程的子进程,waitpid 就会出错返回,这时 errno 被设置为 ECHILD。示例代码:waitpid.c。进程编程基础 进程执行Linux 开发 进程编程基础进程介绍进程介绍进程编程基础进程编程基础进程创建进程创建进程执行进程执行进程等待进程等待进程退出进程退出进程退出方式进程退出方式Linux 下,进程退出的方式有:正常退出正常退出 在 main()函数中调用 return();调用 exit()函数 调用 _exit()函数异常退出异常退
11、出 调用 abort()函数 进程收到某个信号,而该信号使程序终止。不管是哪种退出方式,系统最终都会执行内核中的同一代码。不管是哪种退出方式,系统最终都会执行内核中的同一代码。这段代码用来关闭进程所用已打开的文件描述符,释放它所占用的内存这段代码用来关闭进程所用已打开的文件描述符,释放它所占用的内存和其他资源。和其他资源。进程编程基础 进程退出exit 和和 _exit 调用这两个函数时,系统无条件的停止剩下所有操作,清除包括 PCB在内的各种数据结构,并终止本进程的运行;exit 在头文件 stdlib.h 中声明,其功能由 ANSI C 描述。参数为代表进程正常终止,其他值表示程序执行过程中有错误发生。exit()要先执行一些清除操作,然后将控制权交给内核;_exit()在头文件 unistd.h 中声明,其功能由 POSIX.1 描述。执行后立即返回给内核;示例代码:exit.c,_exit.c。进程编程基础 进程退出谢谢!谢谢!Linux 应用开发 进程编程基础