《《进程控制开发》PPT课件.ppt》由会员分享,可在线阅读,更多相关《《进程控制开发》PPT课件.ppt(68页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第第7章章 进程控制进程控制 Linux进程概述进程概述 Linux进程控制编程进程控制编程 Linux守护进程守护进程实验实验 进程的定义进程的定义进程的参考定义有如下几种:进程的参考定义有如下几种:1、进程是程序的一次执行过程;、进程是程序的一次执行过程;2、进程、进程=PCB+程序程序+数据;数据;3、进程是一个可拥有资源的独立实体,同、进程是一个可拥有资源的独立实体,同时又是一个可以独立调度的基本单位。时又是一个可以独立调度的基本单位。PCB程序程序段段私有私有数据块数据块进程的定义进程的定义进程与程序的区别进程与程序的区别 动态性与静态动态性与静态动态性与静态动态性与静态 进程由进程
2、由进程由进程由“创建创建创建创建”而产生,由而产生,由而产生,由而产生,由“调度调度调度调度”而执行;由而执行;由而执行;由而执行;由得不到资源而得不到资源而得不到资源而得不到资源而阻塞阻塞阻塞阻塞;由撤消而消亡。而程序是静;由撤消而消亡。而程序是静;由撤消而消亡。而程序是静;由撤消而消亡。而程序是静态的,是完成某个特定功能的指令的有序序列,态的,是完成某个特定功能的指令的有序序列,态的,是完成某个特定功能的指令的有序序列,态的,是完成某个特定功能的指令的有序序列,我们把程序看成是一个菜谱,而进程则是按照菜我们把程序看成是一个菜谱,而进程则是按照菜我们把程序看成是一个菜谱,而进程则是按照菜我们
3、把程序看成是一个菜谱,而进程则是按照菜谱进行烹调的过程。谱进行烹调的过程。谱进行烹调的过程。谱进行烹调的过程。结构特征结构特征结构特征结构特征 从结构上看,每个进程是由从结构上看,每个进程是由从结构上看,每个进程是由从结构上看,每个进程是由程序段、数据段和进程序段、数据段和进程序段、数据段和进程序段、数据段和进程控制块三程控制块三程控制块三程控制块三部分组成,总称部分组成,总称部分组成,总称部分组成,总称“进程映像进程映像进程映像进程映像”。程序。程序。程序。程序无控制块。无控制块。无控制块。无控制块。进程与程序的区别进程与程序的区别 并发性并发性并发性并发性 多个进程实体,同存于内存中,能在
4、一段时间内多个进程实体,同存于内存中,能在一段时间内多个进程实体,同存于内存中,能在一段时间内多个进程实体,同存于内存中,能在一段时间内同时执行;程序是不能并发执行的同时执行;程序是不能并发执行的同时执行;程序是不能并发执行的同时执行;程序是不能并发执行的,只有建立了只有建立了只有建立了只有建立了进程,才能并发执行。进程,才能并发执行。进程,才能并发执行。进程,才能并发执行。独立性。独立性。独立性。独立性。进程是系统进行资源分配和调度的一个独立单位;进程是系统进行资源分配和调度的一个独立单位;进程是系统进行资源分配和调度的一个独立单位;进程是系统进行资源分配和调度的一个独立单位;程序则不是。程
5、序则不是。程序则不是。程序则不是。进程具有创建其它进程的功能进程具有创建其它进程的功能小结进程的状态进程的状态运行运行就绪就绪阻塞阻塞进程进程调度调度I/O完成完成时时 间间片片 用用完完等待等待I/O完成完成进程的状态及转变进程的状态及转变进程通常有进程通常有3种状态。种状态。执行态:该进程执行态:该进程正在运行,即进程正在运行,即进程正在占用正在占用CPU。就绪态:进程已就绪态:进程已经具备执行的一切经具备执行的一切条件,正在等待分条件,正在等待分配配CPU的处理时间的处理时间片。片。等待态:进程不等待态:进程不能使用能使用CPU,若等,若等待事件发生(等待待事件发生(等待的资源分配到)则
6、的资源分配到)则可将其唤醒。可将其唤醒。进程状态值说明TASK_RUNNING0就绪TASK_INTERRUPTIBLE1浅度睡眠TASK_UNINTERRUPTIBLE2深度睡眠TASK_ZOMBIE4僵死TASK_STOPPED8暂停Linux进程状态进程状态LinuxLinux进程状态及转换进程状态及转换 fork()TASK_RUNNING就绪TASK_INTERRUPTIBLE浅度睡眠TASK_UNINTERRUPTIBLE深度睡眠TASK_STOPPED暂停TASK_ZOMBIE僵死占有CPU运行do_exit()schedule()ptrace()schedule()时间片耗尽时
7、间片耗尽等待资源到位等待资源到位sleep_on()schedule()等待资源到位等待资源到位interruptible_sleep_on()schedule()资源到位资源到位wake_up_interruptible()或收到信号wake_up()资源到位资源到位wake_up()收到信号SIGCONTwake_up()TASK_RUNNING进程控制块进程控制块进程控制块是进程存在的标志,每一进程都进程控制块是进程存在的标志,每一进程都有一进程控制块,有一进程控制块,Linux中用数据结构中用数据结构task_struct表示,并将指向每个进程控制块表示,并将指向每个进程控制块的指针保
8、存在一个数组的指针保存在一个数组task中,数组下标的中,数组下标的最大值为最大值为512,表明,表明Linux允许的进程数最多允许的进程数最多可有可有 512个。个。Linux进程控制块也叫进程描述符进程控制块也叫进程描述符(Process Descriptor)进程控制块信息分类进程控制块信息分类状态信息状态信息描述进程状态的变化。描述进程状态的变化。链接信息链接信息描述进程的父子关系。描述进程的父子关系。各种标识符各种标识符用简单数字对进程进行标识。用简单数字对进程进行标识。进程间通信信息进程间通信信息描述多个进程在同一任务上协作工描述多个进程在同一任务上协作工作。作。时间和定时器信息时
9、间和定时器信息描述进程在生存周期内使用描述进程在生存周期内使用CPU时间的统计、计费等信息。时间的统计、计费等信息。调度信息调度信息描述进程优先级、调度策略等信息。描述进程优先级、调度策略等信息。文件系统信息文件系统信息对进程使用文件情况进行记录。对进程使用文件情况进行记录。虚拟内存信息虚拟内存信息描述每个进程拥有的地址空间。描述每个进程拥有的地址空间。处理器环境信息处理器环境信息描述进程的执行环境描述进程的执行环境(处理器的寄存处理器的寄存器及堆栈等器及堆栈等)struct task_struct volatile long state;struct thread_info*thread_i
10、nfo;atomic_t usage;unsigned long flags;unsigned long ptrace;int lock_depth;#if defined(CONFIG_SMP)&defined(_ARCH_WANT_UNLOCKED_CTXSW)int oncpu;#endifint prio,static_prio;struct list_head run_list;prio_array_t*array;unsigned short ioprio;unsigned long sleep_avg;LinuxLinux进程控制块数据结构进程控制块数据结构 unsigned l
11、ong long timestamp,last_ran;unsigned long long sched_time;int activated;unsigned long policy;cpumask_t cpus_allowed;unsigned int time_slice,first_time_slice;#ifdef CONFIG_SCHEDSTATSstruct sched_info sched_info;#endifstruct list_head tasks;struct list_head ptrace_children;struct list_head ptrace_list
12、;struct mm_struct*mm,*active_mm;struct linux_binfmt*binfmt;LinuxLinux进程控制块数据结构进程控制块数据结构 long exit_state;int exit_code,exit_signal;int pdeath_signal;unsigned long personality;unsigned did_exec:1;pid_t pid;pid_t tgid;struct task_struct*real_parent;struct task_struct*parent;struct list_head children;st
13、ruct list_head sibling;struct task_struct*group_leader;LinuxLinux进程控制块数据结构进程控制块数据结构struct pid pidsPIDTYPE_MAX;struct completion*vfork_done;int _user*set_child_tid;int _user*clear_child_tid;unsigned long rt_priority;cputime_t utime,stime;unsigned long nvcsw,nivcsw;struct timespec start_time;unsigned
14、long min_flt,maj_flt;cputime_t it_prof_expires,it_virt_expires;unsigned long long it_sched_expires;struct list_head cpu_timers3;uid_t uid,euid,suid,fsuid;gid_t gid,egid,sgid,fsgid;struct group_info*group_info;LinuxLinux进程控制块数据结构进程控制块数据结构kernel_cap_t cap_effective,cap_inheritable,cap_permitted;unsign
15、ed keep_capabilities:1;struct user_struct*user;#ifdef CONFIG_KEYSstruct key*thread_keyring;unsigned char jit_keyring;#endifint oomkilladj;char commTASK_COMM_LEN;int link_count,total_link_count;struct sysv_sem sysvsem;struct thread_struct thread;struct fs_struct*fs;LinuxLinux进程控制块数据结构进程控制块数据结构 struct
16、 files_struct*files;struct namespace*namespace;struct signal_struct*signal;struct sighand_struct*sighand;sigset_t blocked,real_blocked;struct sigpending pending;unsigned long sas_ss_sp;size_t sas_ss_size;int(*notifier)(void*priv);void*notifier_data;sigset_t*notifier_mask;void*security;struct audit_c
17、ontext*audit_context;seccomp_t seccomp;u32 parent_exec_id;u32 self_exec_id;LinuxLinux进程控制块数据结构进程控制块数据结构spinlock_t alloc_lock;spinlock_t proc_lock;void*journal_info;struct reclaim_state*reclaim_state;struct dentry*proc_dentry;struct backing_dev_info*backing_dev_info;struct io_context*io_context;unsig
18、ned long ptrace_message;siginfo_t*last_siginfo;wait_queue_t*io_wait;u64 rchar,wchar,syscr,syscw;LinuxLinux进程控制块数据结构进程控制块数据结构#if defined(CONFIG_BSD_PROCESS_ACCT)u64 acct_rss_mem1;u64 acct_vm_mem1;clock_t acct_stimexpd;#endif#ifdef CONFIG_NUMA struct mempolicy*mempolicy;short il_next;#endif#ifdef CONF
19、IG_CPUSETSstruct cpuset*cpuset;nodemask_t mems_allowed;int cpuset_mems_generation;#endifatomic_t fs_excl;LinuxLinux进程控制块数据结构进程控制块数据结构每个进程都有一个唯一的标识符每个进程都有一个唯一的标识符PID,内核通过这,内核通过这个标识符来识别不同的进程,用户程序通过个标识符来识别不同的进程,用户程序通过PID对对进程发号施令进程发号施令,PID是是32位的无符号整数,它被顺位的无符号整数,它被顺序编号序编号,1、2、.、32767每个进程都属于某个用户组。每个进程都属于某
20、个用户组。task_struct结构中还定义有用户标识符结构中还定义有用户标识符UID(User Identifier)和组标识符)和组标识符GID(Group Identifier)这两种标识符用于系统的安全控制这两种标识符用于系统的安全控制,系统通过这系统通过这两种标识符控制进程对系统中文件和设备的访问。两种标识符控制进程对系统中文件和设备的访问。进程标识符进程标识符PIDLinux下进程地址空间下进程地址空间Linux系统是一个多进程的系统,每个进程都是一系统是一个多进程的系统,每个进程都是一个独立的运行单位,运行在独立的虚拟地址空间,个独立的运行单位,运行在独立的虚拟地址空间,即使一个
21、进程发生异常,它也不会影响到系统中即使一个进程发生异常,它也不会影响到系统中的其他进程。的其他进程。Linux下进程地址空间包含下进程地址空间包含3个段,分别为个段,分别为“数据数据段段”、“代码段代码段”和和“堆栈段堆栈段”。数据段数据段:存放全局变量、常数以及动态分配的数据。数:存放全局变量、常数以及动态分配的数据。数据段又可以再分成据段又可以再分成普通数据段普通数据段(包括可读可写(包括可读可写/只读数据只读数据段,存放静态初始化的全局变量或常量)、段,存放静态初始化的全局变量或常量)、BSS数据段数据段(存放未初始化的全局变量)以及(存放未初始化的全局变量)以及堆堆(存放动态分配的(存
22、放动态分配的数据)。数据)。代码段代码段:存放程序代码。:存放程序代码。堆栈段堆栈段:存放子程序的返回地址、参数以及程序的局部:存放子程序的返回地址、参数以及程序的局部变量等。变量等。Linux下进程地址空间下进程地址空间堆栈堆栈堆堆数据段数据段(可读/只读)代码段代码段存放传递参数及环境变量存放传递参数及环境变量BSS 数据段数据段 低地址低地址高地址高地址Linux下进程的运特模式下进程的运特模式在在Linux系统中,进程的执行模式划分为用户模式和内核系统中,进程的执行模式划分为用户模式和内核模式模式用户模式:若进程执行的是用户程序、应用程序或用户模式:若进程执行的是用户程序、应用程序或者
23、内核之外的系统程序,则处在该模式下,也称为者内核之外的系统程序,则处在该模式下,也称为用户态用户态内核模式:用户程序执行中出现系统调用或者发生内核模式:用户程序执行中出现系统调用或者发生中断事件,就要运行核心程序,进程模式就转变为中断事件,就要运行核心程序,进程模式就转变为内核模式,也称进入核心态内核模式,也称进入核心态内核模式下运行的进程可以执行机器的特权指令,访问内核模式下运行的进程可以执行机器的特权指令,访问受操作系统保护的资源受操作系统保护的资源第第7章章 进程控制进程控制 Linux进程概述进程概述 Linux进程控制编程进程控制编程 Linux守护进程守护进程实验实验 创建进程创建
24、进程fork()fork1.c.#include#include#include int main()pid_t pid;char*message;int n;printf(“fork program startingn”);pid=fork();switch(pid)case-1:perror(“fork failed”);exit(1);case 0:message=“This is the child”;n=5;break;default:message=“This is the parent”;n=3;break;for(;n 0;n-)puts(message);sleep(1);e
25、xit(0);示例补示例补1$./fork1fork program startingThis is the parentThis is the childThis is the parentThis is the childThis is the parentThis is the child$This is the childThis is the childfork()从已存在的进程中创建一个称为子进从已存在的进程中创建一个称为子进程的新进程,而原进程称为父进程。程的新进程,而原进程称为父进程。fork()使用使用“写时复制写时复制”技术产生新进程。技术产生新进程。即只复制父进程的控制块
26、、内核栈与页表并即只复制父进程的控制块、内核栈与页表并作必要修改即产生一个新作必要修改即产生一个新/子进程。让子进子进程。让子进程共享父进程的地址空间,包括代码段、进程共享父进程的地址空间,包括代码段、进程堆栈、内存信息、打开的文件描述符、资程堆栈、内存信息、打开的文件描述符、资源限制和控制终端等。当父、子进程中有一源限制和控制终端等。当父、子进程中有一个要写入时才进行复制个要写入时才进行复制/增加一个拷贝,如增加一个拷贝,如果子进程产生后立即调用果子进程产生后立即调用exec()函数,就可函数,就可避免写时拷贝的额外开销。避免写时拷贝的额外开销。父子两个进程运行同一个程序,与创建进程父子两个
27、进程运行同一个程序,与创建进程的初衷相左,因此需要用一种方式来区分它的初衷相左,因此需要用一种方式来区分它们,并使它们运行不同的程序,否则,这两们,并使它们运行不同的程序,否则,这两个进程不可能做不同的事。什么方式?个进程不可能做不同的事。什么方式?条件或分支指令条件或分支指令exec()函数函数进程结构进程创建进程创建代码数据mm_structtask_structvm_area_structmmvmmap进程地址空间进程地址空间pdg页表页表物理内存物理内存代码数据mm_structtask_structvm_area_structmmvmmap进程地址空间进程地址空间pdg页表页表物理内
28、存物理内存父父进进程程task_structmm子子进进程程写时复制;让子进写时复制;让子进程先运行程先运行,其可能会其可能会执行执行exec()读入其读入其代码执行代码执行.进程创建进程创建mm_structvm_area_structvmmappdg页表页表fork()进程结构进程创建进程创建代码数据mm_structtask_structvm_area_structmmvmmap进程地址空间pdg页表页表物理内存物理内存task_structmm父父进进程程子子进进程程vfork()exec函数族(函数族(1)exec函数族提供了一个在进程中启动另一个函数族提供了一个在进程中启动另一个程
29、序运行的方法。它可以根据指定的文件名程序运行的方法。它可以根据指定的文件名或目录名找到可执行文件,并用它来取代原或目录名找到可执行文件,并用它来取代原调用进程的数据段、代码段和堆栈段,在执调用进程的数据段、代码段和堆栈段,在执行完之后,原调用进程的内容除了进程号外,行完之后,原调用进程的内容除了进程号外,其他全部被新的进程替换了。另外,这里的其他全部被新的进程替换了。另外,这里的可执行文件既可以是二进制文件,也可以是可执行文件既可以是二进制文件,也可以是Linux下任何可执行的脚本文件。下任何可执行的脚本文件。使用使用exec函数族主要有两种情况函数族主要有两种情况 当进程认为自己不能再为系统
30、和用户做出当进程认为自己不能再为系统和用户做出任何贡献时,就可以调用任何贡献时,就可以调用exec函数族中的函数族中的任意一个函数让自己重生;任意一个函数让自己重生;如果一个进程想执行另一个程序,那么它如果一个进程想执行另一个程序,那么它就可以调用就可以调用fork()函数新建一个进程,然函数新建一个进程,然后调用后调用exec函数族中的任意一个函数,这函数族中的任意一个函数,这样看起来就像通过执行应用程序而产生了样看起来就像通过执行应用程序而产生了一个新进程(这种情况非常普遍)。一个新进程(这种情况非常普遍)。exec函数族(函数族(2)exec函数族对应位的含义函数族对应位的含义exec函
31、数族中各位的含义函数族中各位的含义示例示例阅读并运行示例阅读并运行示例7-2-2-1阅读并运行示例阅读并运行示例7-2-2-2阅读并运行示例阅读并运行示例7-2-2-3阅读并运行示例阅读并运行示例7-2-2-4/*execlp.c*/#include#include#include int main()int ret;if(ret=fork()=0)/*调用调用execlp函数,这里相当于调用了函数,这里相当于调用了ps-ef命令命令*/if(ret=execlp(ps,ps,-ef,NULL)0)printf(Execlp errorn);return ret;/*execl.c*/#inc
32、lude#include#include int main()int ret;if(ret=fork()=0)/*调用调用execl函数,注意这里要给出函数,注意这里要给出ps程序所在的完整路径程序所在的完整路径*/if(ret=execl(/bin/ps,ps,-ef,NULL)0)printf(Execl errorn);return ret;/*execle.c*/#include#include#include int main()/*命令参数列表,必须以命令参数列表,必须以NULL结尾结尾*/char*envp=PATH=/tmp,USER=david,NULL;if(fork()=
33、0)/*调用调用execle函数,注意这里也要指出函数,注意这里也要指出env的完整路径的完整路径*/if(execle(/usr/bin/env,env,NULL,envp)0)printf(Execle errorn);$./execlePATH=/tmpUSER=david/*evecve.c*/#include#include#include int main()/*命令参数列表,必须以命令参数列表,必须以NULL结尾结尾*/char*arg=env,NULL;char*envp=PATH=/tmp,USER=david,NULL;if(fork()=0)if(execve(/usr/
34、bin/env,arg,envp)0)printf(Execve errorn);$./execlePATH=/tmpUSER=davidexit()和和_exit()(1)exit()和和_exit()函数都是用来终止进程的。函数都是用来终止进程的。_exit()函数的作用是直接调用函数的作用是直接调用exit系统调用使进系统调用使进程停止运行,清除其使用的内存空间,并清除其程停止运行,清除其使用的内存空间,并清除其在内核中的各种数据结构;在内核中的各种数据结构;exit()函数在执行退出之前还要多做一些工作,即函数在执行退出之前还要多做一些工作,即在调用在调用exit系统之前要检查文件的打
35、开情况,把文系统之前要检查文件的打开情况,把文件缓冲区中的内容写回文件,就是图中的件缓冲区中的内容写回文件,就是图中的“清理清理I/O缓冲缓冲”一项。一项。由于在由于在Linux的标准函数库中,有一种被称的标准函数库中,有一种被称作作“缓冲缓冲I/O(buffered I/O)”操作,其特操作,其特征就是对应每一个打开的文件,在内存中都征就是对应每一个打开的文件,在内存中都有一片缓冲区。每次读文件时,会连续读出有一片缓冲区。每次读文件时,会连续读出若干条记录,这样在下次读文件时就可以直若干条记录,这样在下次读文件时就可以直接从内存的缓冲区中读取;同样,每次写文接从内存的缓冲区中读取;同样,每次
36、写文件的时候,也仅仅是写入内存中的缓冲区,件的时候,也仅仅是写入内存中的缓冲区,等满足了一定的条件(如达到一定数量或遇等满足了一定的条件(如达到一定数量或遇到特定字符等),再将缓冲区中的内容一次到特定字符等),再将缓冲区中的内容一次性写入文件。性写入文件。exit()和和_exit()(2)这种技术大大增加了文件读写的速度,但也为编程带来这种技术大大增加了文件读写的速度,但也为编程带来了一些麻烦。比如有些数据,认为已经被写入到文件中,了一些麻烦。比如有些数据,认为已经被写入到文件中,实际上因为没有满足特定的条件,它们还只是被保存在缓实际上因为没有满足特定的条件,它们还只是被保存在缓冲区内,这时
37、用冲区内,这时用_exit()函数直接将进程关闭,缓冲区中函数直接将进程关闭,缓冲区中的数据就会丢失。因此,若想保证数据的完整性,就一定的数据就会丢失。因此,若想保证数据的完整性,就一定要使用要使用exit()函数。函数。/*exit.c*/#include#include int main()printf(Using exit.n);printf(This is the content in buffer);exit(0);/*_exit.c*/#include#include int main()printf(Using _exit.n);printf(This is the conten
38、t in buffer);_exit(0);./exitUsing exit This is the content in buffer$./_exitUsing exit$示例示例7-2-3Printf()缓冲缓冲I/O方式,遇到方式,遇到“n”时自动从缓中区中时自动从缓中区中将数据读出将数据读出教材关于教材关于exit()的小知识不正确。的小知识不正确。调用exit()后,进程处于僵死状态(TASK_ZOMBIE),释放除内核栈与控制块task_struct外的所有资源,直到父进程调用wait()后才释放全部资源。wait()和和waitpid()(1)wait()函数是用于使父进程(也就
39、是调用函数是用于使父进程(也就是调用wait()的的进程)阻塞,直到一个子进程结束或者接到了一进程)阻塞,直到一个子进程结束或者接到了一个指定的信号为止。个指定的信号为止。如果该父进程没有子进程或者他的子进程已经结如果该父进程没有子进程或者他的子进程已经结束,则束,则wait()就会立即返回。就会立即返回。waitpid()的作用和的作用和wait()一样,但它并不一一样,但它并不一定要等待第一个子进程的终止,可以通过选定要等待第一个子进程的终止,可以通过选项设置它的行为,如可提供一个非阻塞版本项设置它的行为,如可提供一个非阻塞版本的的wait()功能。功能。实际上实际上wait()函数只是函
40、数只是waitpid()函数的一个函数的一个特例,在特例,在Linux内部实现内部实现wait()函数时直接调函数时直接调用的就是用的就是waitpid()函数函数。wait()和和waitpid()(2)wait.c.#include#include#include#include int main()pid_t pid;char*message;int n;int exit_code;printf(“fork program startingn”);pid=fork();switch(pid)case-1:perror(“fork failed”);exit(1);case 0:messa
41、ge=“This is the child”;n=5;exit_code=37;break;default:message=“This is the parent”;n=3;exit_code=0;break;for(;n 0;n-)puts(message);sleep(1);exit(0);示例补示例补被取代$./fork1fork program startingThis is the parentThis is the childThis is the parentThis is the childThis is the parentThis is the child$This is
42、the childThis is the child$./waitfork program startingThis is the childThis is the parentThis is the parentThis is the childThis is the parentThis is the childThis is the childThis is the childChild has finished:PID=1582Child exited with code 37$示例示例阅读并执行示例阅读并执行示例7-2-4/*waitpid.c*/int main()pid_t pc
43、,pr;pc=fork();if(pc 0)printf(Error forkn);else if(pc=0)/*子进程子进程*/*子进程暂停子进程暂停5s*/sleep(5);/*子进程正常退出子进程正常退出*/exit(0);else/*父进程父进程*/*循环测试子进程是否退出循环测试子进程是否退出*/do pr=waitpid(pc,NULL,WNOHANG);/*父进程不阻塞父进程不阻塞*/if(pr=0)/*若子进程还未退出,则父进程暂停若子进程还未退出,则父进程暂停1s*/printf(The child process has not exitedn);sleep(1);whil
44、e(pr=0);if(pr=pc)printf(Get child exit code:%dn,pr);else printf(Some error occured.n);The child process has not exitedThe child process has not exitedThe child process has not exitedThe child process has not exitedThe child process has not exitedGet child exit code:75当pr=waitpid(pc,NULL,0)or pr=wait
45、(NULL)时,输出?第第7章章 进程控制进程控制 Linux进程概述进程概述 Linux进程控制编程进程控制编程 Linux守护进程守护进程实验实验 Linux守护进程守护进程 守护进程:后台服务进程守护进程:后台服务进程Daemon进程,进程,是一个生存期较长的进程,通常独立于控制是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理终端并且周期性地执行某种任务或等待处理某些发生的事件,守护进程常常在系统引导某些发生的事件,守护进程常常在系统引导载入时启动,在系统关闭时终止。载入时启动,在系统关闭时终止。Linux有很多系统服务,大多数服务都是通有很多系统服务,大多数
46、服务都是通过守护进程实现的,如第二章讲到多种系统过守护进程实现的,如第二章讲到多种系统服务都是守护进程。守护进程还能完成许多服务都是守护进程。守护进程还能完成许多系统任务,例如,作业规划进程系统任务,例如,作业规划进程crond、打、打印进程印进程lqd等也都是守护进程。等也都是守护进程。Linux中每一个系统与用户进行交流的界面中每一个系统与用户进行交流的界面称为终端,每一个从此终端开始运行的进程称为终端,每一个从此终端开始运行的进程都会依附于这个终端,这个终端就称为这些都会依附于这个终端,这个终端就称为这些进程的控制终端,当控制终端被关闭时,相进程的控制终端,当控制终端被关闭时,相应的进程
47、都会自动关闭。但是守护进程却能应的进程都会自动关闭。但是守护进程却能够突破这种限制,它从被执行开始运转,直够突破这种限制,它从被执行开始运转,直到整个系统关闭时才会退出。到整个系统关闭时才会退出。如果想让某个进程不因为用户、终端或者其如果想让某个进程不因为用户、终端或者其他的变化而受到影响,那么就必须把这个进他的变化而受到影响,那么就必须把这个进程变成一个守护进程。程变成一个守护进程。守护进程守护进程 的编写流程的编写流程会话期是一个或多个进程组的集合。一个会话始于用户登录,止于用户退出,此期间该用户运行的所有进程都属于这个会话期。12345摆脱原会话的控制摆脱原进程组的控制摆脱控制终端的控制
48、/*dameon.c 创建守护进程实例创建守护进程实例*/int main()pid_t pid;int i,fd;char *buf=This is a Daemonn;pid=fork();/*第一步第一步*/if(pid 0)exit(0);/*父进程推出父进程推出*/setsid();/*第二步第二步*/chdir(/);/*第三步第三步*/umask(0);/*第四步第四步*/for(i=0;i getdtablesize();i+)/*第五步第五步*/close(i);/*这时创建完守护进程,以下开始正式进入守护进程工作这时创建完守护进程,以下开始正式进入守护进程工作*/while
49、(1)if(fd=open(/tmp/daemon.log,O_CREAT|O_WRONLY|O_APPEND,0600)0)printf(Open file errorn);exit(1);write(fd,buf,strlen(buf)+1);close(fd);sleep(10);exit(0);$tail f/tmp/dawmon.logThis is a DaemonThis is a DaemonThis is a DaemonThis is a Daemon$ps ef|grep daemon 76 root 1272 S ./daemon 85 root 1520 S grep
50、 daemon守护进程的出错处理守护进程的出错处理 由于守护进程完全脱离了控制终端,因此,不能由于守护进程完全脱离了控制终端,因此,不能像其他普通进程一样将错误信息输出到控制终端像其他普通进程一样将错误信息输出到控制终端来通知程序员。来通知程序员。守护进程的一种通用的办法是使用守护进程的一种通用的办法是使用syslog服务,将服务,将程序中的出错信息输入到系统日志文件中,从而程序中的出错信息输入到系统日志文件中,从而可以直观地看到程序的问题所在。可以直观地看到程序的问题所在。syslog是是Linux中的系统日志管理服务,通过守护中的系统日志管理服务,通过守护进程进程syslogd来维护。该守