版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Linux进程和线程编程,1、Linux中的进程相关概念 2、Linux中的进程的创建 3、Linux中的进程的管理和守护进程,6.1 进程的概述,时间和空间是计算机的两个概念,操作系统将者两个概念实现为文件和进程。 进程是一个可以独立的可有OS调度的活动。 进程是一个抽象实体,当它执行的时候需要OS分配资源。 进程是一个正在执行的程序。 进程是一个程序的一次执行。 进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元,6.1 进程的概述,进程的概念主要有两点: 第一,进程是一个实体。每一
2、个进程都有它自己的地址空间,一般情况下,包括文本区域(text region)、数据区域(data region)和堆栈(stack region)。文本区域存储处理器执行的代码;数据区域存储变量和进程执行期间使用的动态分配的内存;堆栈区域存储着活动过程调用的指令和本地变量。 第二,进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时,它才能成为一个活动的实体,我们称其为进程。 进程是操作系统中最基本、重要的概念。 是多道程序系统出现后,为了刻画系统内部出现的动态情况,描述系统内部各道程序的活动规律引进的一个概念,所有多道程序设计操作系统都建立在进程的基础上。 原因原
3、因原因原因 操作系统引入进程的概念的原因: 从理论角度看,是对正在运行的程序过程的抽象; 从实现角度看,是一种数据结构,目的在于清晰地刻划动态系统的内在规律,有效管理和调度进入计算机系统主存储器运行的程序。,6.1 .1进程的描述,进程的种类 交互进程:由一个Shell启动的进程,交互进程既可以在前台运行,也可以在后台运行。 批处理进程:这种进程和终端没有联系,是一个进程序列。 监控进程:也称守护进程,Linux系统启动是启动的进程,并在后台运行。 进程不但包括程序指令和数据,还包括程序计数器和CPU的所有寄存器及其存储临时数据的进程堆栈。 Linux是一个多进程OS,其他进程必须等到当前正在
4、执行的进程交出CPU的控制权后才能被内核调度执行。 当正在运行的进程等待其他系统资源时,linux内核获得CPU的控制权,并将CPU分配给其他正在等待的进程,内核中的调度算法决定将CPU分配给那个进程。,内存是计算机的敏感资源,熟练掌握对内存的操作是一个程序员的必备素质。 数据的内部存储方式:大小端法 在c中,不同的数据类型占用的空间是不同的,例如char类型占用1个字节,而int占用4个字节,6.1 .1进程的描述-进程内存管理-数据内部存储,时间和空间是计算机的两个基本的概念,操作系统将这两个概念实现未进程和文件,。 进程ID是一个进程的基本属性,其作用类似与人的身份证号,根据进程ID用户
5、可以精确的定位一个进程,一个标识符对应于一个进程,多个进程标识符可以对应于一个程序。进程标识符的类型是pit_t,他是一个无符号整数。,6.1 .1进程的描述-进程标识符进程ID,使用PS查看当前进程 ps -u 用户名 第一列是进程id最后一列是对应的程序名称,6.1 .1进程的描述-进程标识符进程ID,Linux操作系统包括三种不同类型的进程,每种进程都有自己的特点和属性。 交互进程由一个shell启动的进程。交互进程既可以在前台运行,也可以在后台运行(人机交互)。 批处理进程这种进程和终端没有联系,是一个进程序列(多个进程)。 监控进程(也称守护进程)Linux系统启动时启动的进程,并在
6、后台运行。,6.1 .1进程的描述- Linux 进程分类,运行状态:此时进程或者正在运行或者准备运行 等待状态:此时进程在等待一个事件的发生或者某种系统资源 停止状态:此时进程已经被终止 死亡状态:这是一个停止的进程,但是在进程向量数组中占有一个task_struct结构 R (TASK_RUNNING),可执行状态 S (TASK_INTERRUPTIBLE),可中断的睡眠状态。 D (TASK_UNINTERRUPTIBLE),不可中断的睡眠状态。 s进程的领导者 +前台进程,6.2 .1 Linux 进程运行状态,每一个进程有6个重要的ID,分别是进程ID、父进程ID、有效用户ID、有
7、小组ID、实际用户ID和实际组ID。这六个ID保存在内核中的数据结构中,有些时候用户程序需要用到这些ID。 例如在/proc文件系统下每个进程有一个目录,里面存放进程的相关信息,当进程要读取这些文件时,应该先得到当前进程的ID才能确定进入那一个进程相关的子目录,由于这些ID存储在内核之中,因此linux提供一组专门的接口函数访问这些ID值。 Linux环境下使用getpid和getppid函数获得进程和父进程的ID,其函数原型如下: #include Pid_t getpid(void) pid_t getppid(void) 函数成功返回进程的id ,失败返回-1,,6.2 .1 Linux
8、 进程标识符,Linux环境下使用getuid和geteuid函数获得进程用户ID,其函数原型如下: #include uid_t getuid(void) uid_t geteuid(void) 函数成功返回进程的用户id ,失败返回-1. Linux环境下使用getgid和getegid函数获得进程用户组ID,其函数原型如下: #include gid_t getgid(void) gid_t getegid(void) 函数成功返回进程的用户id ,失败返回-1, Pid_t类型参看/usr/include/bits/types.h 实际就是int类型,6.2 .1 Linux 进程标识
9、符,每,6.2 .1 Linux 进程标识符,启动进程和调度进程 1 手动启动:用户直接输入shell命令后回车直接启动进程 前台启动:用户输入一个shell命令后按回车就启动给一个前台进程 后台启动:在shell命令后加入一个“ who,6.2 .2 Linux 进程进程命令- sleep,kill命令杀掉进程 作用:kill命令终止一个进程。 格式:kill -s signal |-p -apid kill -l signal 主要选项如下。 -s:指定发送的信号。 -p:模拟发送信号。 -l:指定信号的名称列表。 pid:要终止的进程的ID号。 signal:表示信号。,6.2 .2 L
10、inux 进程进程命令- kill,说明:kill可将指定的信息送至程序。预设的信息为SIGTERM(15),可将指定程序终止。若仍无法终止该程序,可使用SIGKILL(9)信息尝试强制删除程序。kill命令的工作原理是,向Linux系统的内核发送一个系统操作信号和某个程序的进程标志号,然后系统内核就可以对进程标志号指定的进程进行操作。当需要中断一个前台进程的时候,通常使用Ctrl+C组合键;但是对于一个后台进程,就不是一个组合键所能解决的了,这时就必须使用kill命令。 应用实例如下。 命令执行过程如果出错,用户可用kill来结束任务。对于在后台运行的进程,可以使用kill命令终止: $ k
11、ill -s 9 1827,6.2 .2 Linux 进程进程命令- kill,1at命令:定时运行命令 作用:at命令在指定时刻执行指定的命令序列。 # at 2:05 tomorrow at /home/mj/airplane /home/mj/air-safe at Ctrl+D 2crontab命令 作用:crontab命令用于安装、删除或者列出用于驱动cron后台进程的任务表。然后,该配置由cron守护进程在设定的时间执行。 格式:crontab -u user 文件,6.2 .2 Linux 进程进程命令- at,fork() 创建一个新进程 Wake()唤醒一个进程 Schedu
12、le() 进程调度函数 Exit()退出进程,6.3.1 Linux 进程进程函数,6.3.2 Linux 进程状态,睡眠进程可以被程序再次的唤醒,而僵死进程不会被任何程序唤醒,只能通过命令kill掉 深度睡眠和浅度睡眠进程得到它需要的资源被唤醒,通过schedule()进入执行态,深度睡眠的进程不能被信号或者定时中断唤醒,只有它申请的资源又有效是才能被唤醒。 Linux中,仅等待CPU时间的进程称为就绪进程,它们被放置在一个运行队列中,一个就绪进程的状态标志位为TASK_RUNNING。一旦一个运行中的进程时间片用完, Linux 内核的调度器会剥夺这个进程对CPU的控制权,并且从运行队列中
13、选择一个合适的进程投入运行。当然,一个进程也可以主动释放CPU的控制权。函数schedule()是一个调度函数,它可以被一个进程主动调用,从而调度其它进程占用CPU。一旦这个主动放弃CPU的进程被重新调度占用 CPU,那么它将从上次停止执行的位置开始执行,也就是说它将从调用schedule()的下一行代码处开始执行。有时候,进程需要等待直到某个特定的事件发生,例如设备初始化完成、I/O 操作完成或定时器到时等。在这种情况下,进程则必须从运行队列移出,加入到一个等待队列中,这个时候进程就进入了睡眠状态。,6.3.2 Linux 进程状态,Linux中,仅等待CPU时间的进程称为就绪进程,它们被放
14、置在一个运行队列中,一个就绪进程的状态标志位为TASK_RUNNING。一旦一个运行中的进程时间片用完, Linux 内核的调度器会剥夺这个进程对CPU的控制权,并且从运行队列中选择一个合适的进程投入运行。当然,一个进程也可以主动释放CPU的控制权。函数schedule()是一个调度函数,它可以被一个进程主动调用,从而调度其它进程占用CPU。一旦这个主动放弃CPU的进程被重新调度占用 CPU,那么它将从上次停止执行的位置开始执行,也就是说它将从调用schedule()的下一行代码处开始执行。有时候,进程需要等待直到某个特定的事件发生,例如设备初始化完成、I/O 操作完成或定时器到时等。在这种情
15、况下,进程则必须从运行队列移出,加入到一个等待队列中,这个时候进程就进入了睡眠状态。,6.3.2 Linux 进程状态,父子进程:除了PID号为0号进程以外的其他进程都是有其他进程创建的,创建进程的进程是父进程,被创建的进程称为子进程。 进程是系统中执行的基本单位,liunx系统允许任何而一个用户创建一个子进程。创建之后,子进程存在系统之中,并且独立于父进程。该子进程可以接受系统调度,可以分配得到系统资源,系统可以检测到他的存在,并且赋予他的父进程同样的权利。 Linux使用fork函数创建一个新的进程,其函数原型如下: #include Pid_t fork(void),6.4.1 Linu
16、x进程系统调用-创建进程,Fork函数不需要参数,返回值是一个进程ID,返回值分为3种。 对于父进程,fork函数返回新创建子进程的ID 对于子进程,fork函数返回0 如果出错则返回-1 Fork函数会创建一个新的进程,并从内核中未此进程得到一个新的ID,之后未这个新进程分配内存空间,并将父进程的进程空间代码的内容复制到子进程的进程空间中,包括父进程的数据段和堆栈段,并且和父进程共享代码段。这时系统各种又多了一个进程,这个进程和父进程一模一样,两个进程都要接受系统的调度。,6.4.1 Linux进程系统调用-创建进程fork函数,6.4.1 Linux进程系统调用-创建进程fork函数,子进
17、程完全复制了父进程的地址空间代内容,包括对战段和数据库的内容,子进程并没有复制代码段,而是和父进程公用代码段。 Fork函数的出错情况: Fork有两种情况返回-1 系统中已有太多的进程存在了 调用fork函数的用户进程太多了 一般情况下系统会对进程数目进行限制,如果操作系统对其不加限制,则用户可以利用这一漏洞攻击系统,6.4.1 Linux进程系统调用-创建进程fork函数,由于fork函数完整的拷贝了父进程的整个地址空间,因此,执行速度比较慢,为了加快fork的执行速度,在有些liunx中使用vfork函数。 Vfork函数产生的子进程和父进程完全共享地址空间,包括代码段、数据段和堆栈段,
18、子进程对这些共享资源所做的修改,可以影响到父进程 Vfork函数产生的子进程一定比父进程先运行,也就是说父进程调用了vfork函数后会等待子进程运行后再运行。 Vfork函数创建新的进程,但他不产生父进程的副本,他通过允许父子进程可访问相同物理内存从而为装了对进程地址的真实拷贝,当子进程需要改变内存中的数据时才会拷贝父进程。这就是著名的“写操作时拷贝”copy-on-write技术,6.4.1 Linux进程系统调用-创建进程vfork函数,上面讲了进程的fork函数,很多人有疑问既然所有的进程都是fork创建的,那么linux所有的进程不就几乎全部一样吗,而且就我们的常识而言,当我们执行一个
19、程序时,新产生的进程内容就因该是程序的内容才对。 Linux环境使用exec函数执行一个新程序,该函数在文件系统中搜索指定的路径文件,并将该文件内容复制到调用的exec函数地址空间,取代原来的进程内容。 Exec函数提供了一个在进程中启动另一个程序的方法他可以根据指定的文件名和目录找到可执行代码,并用它来取代原调用进程的数据段代码段和堆栈段,在执行之后,远调用进程的内容中除了进程号以外,其他全部被新的进程替换了。 可执行文件可以是二进制文件也可以是liunx下的脚本文件。,6.4.2 Linux进程系统调用-exec函数,在什么情况下使用exec函数 当有进程认为自己不能再为系统和用户作出任何
20、新贡献了,就可以调用任何exec函数族,让自己以新的面貌重生。 如果一个进程想执行另一程序,它就可以调用fork函数新建一个进程,然后执行任何一个exec函数,这样看起来就像通过执行应用程序而产生了一个新进程一样。,6.4.2 Linux进程系统调用-exec函数,所需头文件#include int execl(const char *path, const char *arg, .); int execlp(const char *file, const char *arg, .); int execle(const char *path, const char *arg, ., char
21、*const envp); int execv(const char *path, char *const argv); int execvp(const char *file, char *const argv); int execve(const char *path, char *const argv, char *const envp); 其中只有execve是真正意义上的系统调用,其它都是在此基础上经过包装的库函数。 exec函数族的函数执行成功后不会返回,因为调用进程的实体,包括代码段,数据段和堆栈等都已经被新的内容取代,只留下进程ID等一些表面上的信息仍保持原样,颇有些神似三十六
22、计中的金蝉脱壳。看上去还是旧的躯壳,却已经注入了新的灵魂。只有调用失败了,它们才会返回一个-1,从原程序的调用点接着往下执行。,6.4.2 Linux进程系统调用-exec函数,Execl的第一个参数是包含路劲的可执行文件,后面是参数列表,列表的第一个为命令path,接着为参数列表,最后必须以null结束。 Execlp的第一个参数可以使用绝对路径或者是相对路径 Excele最后包含指向一个自定义环境变量列表的指针,此列表必须以null结束。 Execv,v表示path后面接受的是一个向量,即指向一个参数列表的指针,注意这个列表的最后一项必须是null Execve path后面的接受一个参数
23、列表向量,并可以指定一个环境变量列表向量 Execvp,第一个参数可以使用相对或者绝对路径,v表示后面接受一个参数列表向量。,6.4.2 Linux进程系统调用-exec函数,对于l表示list,说明执行程序的命令参数以列表的方式提供,并且用null结束。参数的个数没有限制。如下: Char * arg0 , Char * arg1 , Char * arg2 ,null V表示所有的参数以指针数组方式给出,其语法为*const argv,这个数组的每一行是一个命令参数。 E表示传递给新程序的环境变量列表,这个列表是一个数组,数组的每一行表示一个环境变量,如果没有显示的说明环境变量则新程序继承
24、父进程的环境变量。 P表示第一参数不是完整的路径名,这是就要从环境变量中读取环境变量参数组合成一个完整的路径名。那么exec函数就会匹配bin/filename、 usr/bin/filename 直到找到一个正确路径,就将该文件加载到内存执行,如果该文件不存在则,exec函数出错。,6.4.2 Linux进程系统调用-exec函数,Exec函数调用hello程序,使用exec函数调用当前目录下的hello程序,Exec函数调用ps ef命令,Exec函数调用hello程序,带参数的程序执行 ./helloc1 hello world,Linux 进程标识符,#include int main
25、(int argc, char *argv) char *envp=PATH=/tmp, USER=lei, STATUS=testing, NULL; char *argv_execv=echo, excuted by execv, NULL; char *argv_execvp=echo, executed by execvp, NULL; char *argv_execve=env, NULL; if(fork()=0) if(execl(/bin/echo, echo, executed by execl, NULL)0) perror(Err on execl); if(fork()
26、=0) if(execlp(echo, echo, executed by execlp, NULL)0) perror(Err on execlp); if(fork()=0) if(execle(/usr/bin/env, env, NULL, envp)0) perror(Err on execle); if(fork()=0) if(execv(/bin/echo, argv_execv)0) perror(Err on execv); if(fork()=0) if(execvp(echo, argv_execvp)0) perror(Err on execvp); if(fork(
27、)=0) if(execve(/usr/bin/env, argv_execve, envp)0) perror(Err on execve); ,Exec函数注意事项,在使用exec函数时一定要加上错误判断语句 最常见的错误有 找不到制定的文件或者路径 在使用argv和envp时忘记用NULL结束 没有对应可执行文件的运行权限,退出进程exit函数,当一个进程需要退出时,需要调用退出函数 这个退出函数会深入到内核注销掉进程的内核数据结构,并且释放进程资源。 Linux环境下使用exit函数退出进程,其函数原型如下 #include Void exit(int status) int stat
28、us表示退出状态,这一状态是一个整形值,在shell中可以查看这个值。使用echo $? C程序中的return语句被翻译成exit语句 如return 1 - exit(1),exit和_exit区别,Exit是一个标准的库函数,其内部封装了linux的系统调用函数_exit,两者的主要区别在于exit函数会在用户空间做一些善后工作,如清理用户的I/O缓冲区,将其内容写入磁盘文件,之后在释放用户进程的地址空间,而_exit函数直接进入内核释放用户的地址空间,所有用户空间的缓冲区内容都将丢失。 在liunx标准函数库中,有一套称为“高级I/O”的函数,我们熟知的printf()fopen()f
29、read()fwrite()都在此列,他们被称为缓冲IO函数,其特征是每次对应打开文件都会在内存中有一片缓冲区,每次度文件时会读取若干条记录,这样下次读文件就可以直接从缓冲去区中读取,每次写文件件时也是先写到缓冲区,等满足一定条件在将缓冲区中的数据一次性写入文件,这样可以大大提到文件的读写速度。 但是当我们使用_exit函数时就会产生问题,因为改函数直到内核接释放进程,就会产生缓冲区数据丢失的情况。,exit和_exit区别,_exit函数直接清除进程的内存空间,并销毁其在内核中的各种数据结构,exit函数在调用exit系统调用之前要检查文件的打开情况,吧文件的缓冲区中的内容回写到文件,对应与
30、图中“清理缓冲区”一项,exit和_exit区别,说明:在一个进程调用了exit之后,该进程并不会马上完全小时,而是留下一个称为僵尸进程(Zombie)的数据结构。僵尸进程是一种非常特殊的进程,它几乎已经放弃了所有的内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等信息供其它进程收集,除此之外,僵尸进程不再占有任何内存空间。,僵尸进程,每个进程都有一个父进程,当进程退出时,其退出状态可以被父进程得到,父进程调用wait函数取得子进程的退出状态信息。这些退出状态信息保存在内核中,占用很少一块内存空间,当子进程退出时,这些信息仍然被保存在内核中,子进程
31、的进程ID也同样保存在系统进程里列表中,这是的进程称为僵尸进程。 僵尸进程几乎放弃了所有的资源,包括地址空间,僵尸进程不能执行,因此不能被系统调度,也不会占用cpu时间,僵尸进程占用的资源是微乎其微的,僵尸进程会一直存在于系统中直到其父进程得到其结束状态信息。 看起来僵尸进程好像对系统没有什么影响,但是僵尸进程会占用进程pid号,在liunx中严格限制了进程的数量,僵尸进程达到一定数量后就不能再创建新的进程。 因此当父进程使用fork函数创建进程而不调用wait函数时一个个僵尸进程就产生了。,创建一个僵尸进程,僵尸进程,上面的例子在shell中编译 gcc zombile.c o zombil
32、e 执行./zombile 打开另一个终端输入 ps ax父进程休眠时子进程的僵尸状态,Wait函数,Linux下使用wait函数得到进程结束状态信息,其函数原型如下: #include Pid_t wait(int *status) 调用wait函数的进程会阻塞,直到该进程的任意一个子进程结束,wait函数会取得结束进程的信息并返回该子进程的pid,子进程的结束信息保存在参数statloc所指向的内存空间中,如果该进程没有子进程则立即出错返回,返回-1,如果在调用wait函数时已经有若干个子进程结束运行了,则wait函数立即返回,但是具体取得哪一个子进程的信息是不确定的,需要根据wait的返回值该子进程的id来判断。 Status是一个整形指针,是子进程退出时的状态,如果status为N
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026四川雅安市第四人民医院招聘10人备考题库含答案详解(突破训练)
- 2026中国能源建设集团湖南省电力设计院有限公司社会招聘2人备考题库附答案详解(预热题)
- 2026广东东莞市司法局招聘编外聘用人员2人备考题库及答案详解(名师系列)
- 2026广东华南师范大学招聘44人备考题库(编制)及完整答案详解1套
- 2026四川雅安市天全县教育局考核招聘四川省公费师范毕业生28人备考题库及完整答案详解1套
- 2026江苏南通市通州区第三人民医院招聘21人备考题库及一套参考答案详解
- 2026河南郑州市招生考试中心公益性岗位招聘10人备考题库及参考答案详解
- 2026西昌学院招聘年薪制高层次人才32人备考题库及答案详解(典优)
- 2026内蒙古锡林郭勒盟言信人力资源服务有限公司招聘6人备考题库及答案详解1套
- 2026黑龙江哈尔滨启航劳务派遣有限公司派遣到哈尔滨工业大学商学院招聘备考题库附答案详解(研优卷)
- 高中政治案例分析生成式AI辅助的教研资源库构建与教学策略教学研究课题报告
- 如何与“焦虑”做朋友+课件-2025-2026学年高三上学期考前情绪缓解主题班会
- 公务用枪警示教育
- 2026年保温杯可行性研究报告
- 床垫产品讲解培训全流程规范
- 耳部铜砭刮痧课件
- 选矿脱水工(高级)职业技能鉴定考核试卷 (附答案)
- 基于PLC的垃圾智能分类系统设计
- 医院培训课件:《婴儿艾滋病早期诊断滤纸片干血斑样本的采集、处理运输、保存及实验室检测》
- 2025年江苏省中考地理试卷六套附答案
- 2020版ISO9001-14001-45001三标一体化管理评审报告
评论
0/150
提交评论