LINUX环境编程-进程编程.ppt
《LINUX环境编程-进程编程.ppt》由会员分享,可在线阅读,更多相关《LINUX环境编程-进程编程.ppt(35页珍藏版)》请在三一办公上搜索。
1、LINUX应用编程 进程篇,2009年12月22日,2,LINUX应用编程-进程篇,HTTP协议HTML语言CGI编程,3,进程编程 进程与程序,程序是一个包含可执行代码的文件,它放在磁盘等介质上。当程序被操作系统装载到内存并分配给它一定资源后,此时可称为进程。为方便操作系统管理,每个进程都会有一个唯一的非负整数编号。程序是一个静态概念,进程是一个动态概念。,4,进程编程 内存空间,Linux的虚拟地址空间也为04G,Linux将整个4G线性地址空间分为用户空间和内核空间两部分,最高的1G字节(从虚拟地址0 xC0000000到0 xFFFFFFFF),供内核使用,称为“内核空间”。而将较低的
2、3G字节(从虚拟地址0 x00000000到0 xBFFFFFFF),供各个进程使用,称为“用户空间)。因为每个进程可以通过系统调用进入内核,因此,Linux内核由系统内的所有进程共享。于是,从具体进程的角度来看,每个进程可以拥有4G字节的虚拟空间。当进程陷入内核时,内核代表进程运行。,5,进程编程 进程描述,进程描述符:当进程产生时有Linux操作系统分配。内存:用来存放进程要执行的代码和使用的数据。文件描述符:进程运行时打开的文件。认证信息:用户和组ID进程执行环境:各种环境变量资源安排:CPU时间进程状态,6,进程编程 进程状态,用户状态:进程在用户状态下运行的状态。内核状态:进程在内核
3、状态下运行的状态。内存中就绪:进程没有执行,但处于就绪状态,只要内核调度它,就可以执行。内存中睡眠:进程正在睡眠并且进程存储在内存中,没有被交换到SWAP设备。就绪且换出:进程处于就绪状态,但是必须把它换入内存,内核才能再次调度它进行运行。睡眠且换出:进程正在睡眠,且被换出内存。被抢先:进程从内核状态返回用户状态时,内核抢先于它,做了上下文切换,调度了另一个进程。原先这个进程就处于被抢先状态。创建状态:进程刚被创建。该进程存在,但既不是就绪状态,也不是睡眠状态。这个状态是除了进程0以外的所有进程的最初状态。僵死状态(zombie):进程调用exit结束,进程不再存在,但在进程表项中仍有纪录,该
4、纪录可由父进程收集。,7,进程编程 进程状态及转换,图如下:,8,进程调度原理图,9,进程编程 进程的布局,栈用来存放局部变量和函数的返回地址。地址从高到低生长。堆是一块连续的内存,有低地址向高地址生长。需要程序在运行时动态申请和释放。数据段存放了程序运行时的各种数据。代码段存放了可执行指令,一般为只读。,10,进程编程 进程的环境变量,环境变量和命令行参数都放在进程的高地址。环境变量可用 environ来引用。以name=string的形式存放。,#include#include#include extern char*environ;int main(int argc,char*argv)
5、int i=0;for(i=0;environi;i+)printf(%sn,environi);return 0;,11,进程编程 EXIT系统调用,系统调用exit的功能是终止发出调用的进程。它的声明格式如下:#include void exit(int status);#include void _exit(int status);系统调用_exit立即终止发出调用的进程。所有属于该进程的文件描述符都关闭。该进程的所有子进程由进程1(进程init)接收,并对该进程的父进程发 出一个SIGCHLD(子进程僵死)的信号。参数status作为退出的状态值返回父进程,该值可以通过系统调用wait
6、来收集。返回状态码status 只有最低一个字节有效。如果进程是一个控制终端进程,则SIGHUP信号将被送往该控制终端的前台进程。系统调用_exit从不返回任何值给发出调用的进 程;也不刷新I/O缓冲,如果要自动完成刷新,可以用函数调用exit。exit为glibc库函数,它会先运行注册函数,也有可能会进行文件流的关闭操作,之后再调用_exit系统调用。,12,进程编程 RETURN退出进程,return的返回值就是进程终止时的返回状态。如果return没有返回任何值,进程的返回状态是什么?在 gcc加std=c99编译选项下,进程返回状态又是什么?C99:是ISO组织在99年新制定的c标准,
7、使C更可靠。分别用 gcc main.c 和gcc main.c std=c99编译,观察返回值。,13,进程编程 进程终止处理函数,Atexit()函数用于注册一个进程正常终止时要调用的函数,一个进程最多可注册32个终止处理函数。#include int atexit(void(*function)(void);成功返回0,失败返回非0。参数为函数指针,此函数会在进程调用exit时调用。在main函数返回出,分别用return、exit(0)_exit(0),看其中的区别。_exit函数是不会调用注册函数的。void exit_handler(void)printf(Im in exit h
8、andlern);int main(int argc,char*argv)if(0!=atexit(exit_handler)printf(register exit function handler failed!n);return-1;printf(before exitn);exit(0);/_exit(0);return 0;,14,进程编程 getenv、setenv函数,getenv用来获取指定环境变量。#include char*getenv(const char*name);参数name为环境变量的名称,如 PATH,SHELL 等。如果环境变量存在那么返回该环境变量的值,否则
9、为NULLsetenv用来设置环境变量,会把value拷贝到环境变量所在的内存区域。#include int setenv(const char*name,const char*value,int overwrite);参数name为环境变量的名称,value为该环境变量的值。如果环境变量已经存在,overwrite非0时,改变该环境变量的值。overwrite为0时,什么都不做直接返回。成功返回0,失败返回-1(一般为放置环境变量的内存空间不够)。环境变量都是以 name=string的形式存放。,15,进程编程 putenv、clearenv函数,putenv 无论环境变量是否存在,都会使
10、设置值生效。#include int putenv(char*string);参数string的格式为 name=string成功返回0,失败返回非0putenv()函数并不拷贝环境变量字符串到进程环境表,只是存放环境变量数值的指针,而setenv()函数则完全拷贝环境变量字符串到进程环境表。分别用 gcc putenv.c 和gcc putenv.c DLOCAL g编译,产看运行结果。把putenv.c中的putenv换成setenv看结果。clearenv清除所有的环境变量,并且把environ设置为NULL。unsetenv清除名字为name的环境变量。#include int cle
11、arenv(void);int unsetenv(const char*name);,16,进程编程 跨函数跳转,goto只能在函数中跳转,如果要求从一个函数跳到另外一个函数?用setjmp和longjmp。跨函数的跳转主要用在调用函数层次较深时,为了节约函数的返回时间。如右假设我们从a函数调用到了z函数。,a函数,b函数,r函数,z函数,17,进程编程 setjmp、longjmp函数,setjmp用来设置返回点,保存当前的寄存器值。#include int setjmp(jmp_buf env);void longjmp(jmp_buf env,int val);参数jmp_buf env
12、用来保存当前寄存器值。longjmp会根据env跳转到setjmp处。一个setjmp可以对应n个longjmp,可以用setjmp的返回值来区分。如果成功setjmp返回0,如果是从longjmp返回的,那么返回值有longjmp的第二个参数决定。所以longjmp的第二个参数不可以为0,否则无法判断setjmp是如何返回的。longjmp的第一个参数是setjmp返回的,第二个参数是给setjmp的返回值。当longjmp返回后,setjmp所在函数中的自动变量恢复到调用setjmp时的值。如果变量是保存在内存中的,那么它的值仍然是调用longjmp的时候的值。当你希望变量值在setjmp
13、和longjmp时仍然保持其值,但必须用volatile说明该变量,并且需打开-O优化选项。gcc setjmp.c 和 gcc setjmp.c O观察运行结果。,18,进程编程 getpid、getppid函数,getpid得到自己的进程ID,getppid得到自己父进程ID#include#include pid_t getpid(void);pid_t getppid(void);返回值为进程ID,进程ID一般为一非负整数值。,19,进程编程 fork:进程的创建,我们可以在shell里敲入命令的方式来创建进程,也可以在在程序中通过调用fork系统调用来生成新的进程。新产生的进程我们称
14、他为子进程。init进程的进程ID为1,是一个特殊的用户进程。它会收集孤儿进程(父进程已退出的子进程),并结束它们。fork会产生一个新的进程。#include pid_t fork(void);返回值为-1时,创建子进程失败。返回0时,子进程开始执行。返回 0时,父进程开始执行。父子进程都是从fork之后开始执行。到底是父进程还是子进程先开始执行,看操作系统的调度算法。当你的程序执行到fork语句时:操作系统会复制一个与父进程完全相同的子进程。新进程和原有进程共享代码空间,可执行程序是同一个程序。Linux操作系统会为新进程产生一个ID和进程控制块。当子进程或者父进程不进行写操作时,父子进程
15、共享一分数据,当有写操作时,数据会分离(称为写时复制Copy-On-Write),互不干涉。子进程/父进程对数据所做的任何修改,都不会影响另一方。,20,进程编程 写时复制,1.父子进程均无写操作时:,2.父进程或者子进程有些操作时,子进程或父进程将新产生一份进程的数据拷贝,然后再修改。,21,进程编程 子进程的继承,知道子进程自父进程继承什么或未继承什么将有助于我们。下面这个名单会因为不同Unix的实现而发生变化,所以或许准确性有了水份。请注意子进程得到的是这些东西的 拷贝,不是它们本身。由子进程自父进程继承到:进程的资格(真实(real)/有效(effective)/已保存(saved)用
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- LINUX 环境 编程 进程

链接地址:https://www.31ppt.com/p-6511300.html