第04部分进程与信号_第1页
第04部分进程与信号_第2页
第04部分进程与信号_第3页
第04部分进程与信号_第4页
第04部分进程与信号_第5页
已阅读5页,还剩28页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第5部分进程与信号1.进程2进程定义了一个计算的基本单元,可以认为是一个程序的一次运行。它是一个动态实体,是独立的任务。它拥有独立的地址空间、执行堆栈、文件描述符等。每个进程拥有独立的地址空间,进程间正常情况下,互不影响,一个进程的崩溃不会造成其他进程的崩溃。当进程间共享某一资源时,需注意两个问题:同步问题和通信问题。进程

3进程标识

task_structtask_structtask_struct…pid_1pid_2pid_Npid_tpid=getpid();pid_tppid=getppid();4内存空间32位Linux的虚拟地址空间也为0~4G,Linux将整个4G线性地址空间分为用户空间和内核空间两部分,最高的1G字节(从虚拟地址0xC0000000到0xFFFFFFFF),供内核使用,称为“内核空间”。将较低的3G字节(从虚拟地址0x00000000到0xBFFFFFFF),供各个进程使用,称为“用户空间)。因为每个进程可以通过系统调用进入内核,因此,Linux内核由系统内的所有进程共享。于是,从具体进程的角度来看,每个进程可以拥有4G字节的虚拟空间。当进程陷入内核时,内核代表进程运行。5进程描述进程描述符:进程产生时由Linux操作系统分配。内存:用来存放进程要执行的代码和使用的数据。文件描述符:进程运行时打开的文件。认证信息:用户和组ID进程执行环境:各种环境变量资源安排:CPU时间进程状态6进程状态内存中就绪:进程没有执行,但处于就绪状态,只要内核调度它,就可以执行。内存中睡眠:进程正在睡眠并且进程存储在内存中,没有被交换到SWAP设备。就绪且换出:进程处于就绪状态,但是必须把它换入内存,内核才能再次调度它进行运行。睡眠且换出:进程正在睡眠,且被换出内存。被抢先:进程从内核状态返回用户状态时,内核抢先于它,做了上下文切换,调度了另一个进程。原先这个进程就处于被抢先状态。创建状态:进程刚被创建。该进程存在,但既不是就绪状态,也不是睡眠状态。这个状态是除了进程0以外的所有进程的最初状态。僵死状态(zombie):进程调用exit结束,进程不再存在,但在进程表项中仍有纪录,该纪录可由父进程收集。7进程状态状态8进程调度原理图9进程的布局栈用来存放局部变量和函数的返回地址。地址从高到低生长。堆是一块连续的内存,有低地址向高地址生长。需要程序在运行时动态申请和释放。数据段存放了程序运行时的各种数据。代码段存放了可执行指令,一般为只读。10进程的环境变量环境变量和命令行参数都放在进程的高地址。环境变量可用environ来引用。

以name=string的形式存放。#include<stdio.h>

#include<stdlib.h>

#include<unistd.h>

externchar**environ;

intmain(intargc,char**argv){

inti=0;

for(i=0;environ[i];i++){ printf("%s\n",environ[i]);

}

return0;

}11进程的环境变量getenv用来获取指定环境变量。

#include<stdlib.h>char*getenv(constchar*name);参数name为环境变量的名称,如PATH,SHELL等。如果环境变量存在那么返回该环境变量的值,否则为NULLsetenv用来设置环境变量,会把value拷贝到环境变量所在的内存区域。

#include<stdlib.h>intsetenv(constchar*name,constchar*value,intoverwrite);参数name为环境变量的名称,value为该环境变量的值。如果环境变量已经存在,overwrite非0时,改变该环境变量的值。overwrite为0时,什么都不做直接返回。成功返回0,失败返回-1(一般为放置环境变量的内存空间不够)。环境变量都是以name=string的形式存放。12创建进程初始进程fork初始进程继续执行新进程返回新进程pid返回0pid=fork();switch(pid){case-1:/*Error*/

…case0:/*子进程*/

…default:/*父进程*/

…}13两种创建进程的方法可以通过调用fork或vfork函数来创建新的进程。fork用于创建普通进程,采用copyonwrite方式进行源拷贝。Vfork用于完全共享的创建,新老进程共享同新的资源。14两种创建进程的方法头文件:sys/types.hunistd.hpid_tfork(void)返回:调用一次,返回两次。父进程中返回子进程的进程ID,子进程返回0,-1-出错fork后,子进程和父进程继续执行fork()函数后的指令。子进程拥有父进程的数据空间、堆栈的副本。如果父子进程同时对同一文件描述字操作,而又没有任何形式的同步,则会出现混乱的状况;父进程中调用fork之前打开的所有描述字在函数fork返回之后子进程会得到一个副本。fork后,父子进程均需要将自己不使用的描述字关闭。父子进程的执行次序不确定。15两种创建进程的方法#include<sys/types.h>#include<unistd.h>pid_tvfork(void);该系统调用基本上与fork相同,在BSD3.0中开始出现,主要为了解决fork昂贵的开销。两者的基本区别在于当使用vfork()创建新进程时,父进程将被暂时阻塞,而子进程则可以借用父进程的地址空间,直到子进程退出,至此父进程才继续执行。16getpid、getppid函数getpid得到自己的进程ID,

getppid得到自己父进程ID

#include<sys/types.h>#include<unistd.h>pid_tgetpid(void);pid_tgetppid(void);返回值为进程ID,进程ID一般为一非负整数值。17两种创建进程的方法(例)??18进程终止进程的终止存在两个可能:父进程先于子进程终止(init进程领养)子进程先于主进程终止进程的终止的方法:进程执行exit进程的main函数执行return进程收到了无法处理的信号$kill-sSIGKILL2839319进程终止对子进程先于父进程终止情况,系统内核为子进程保留一定的状态信息:进程ID、终止状态、CPU时间等;当父进程调用wait或waitpid函数时,获取这些信息。当子进程正常或异常终止时,系统内核向其父进程发送SIGCHLD信号;缺省情况下,父进程忽略该信号,或者提供一个该信号发生时即被调用的函数。(???)20僵死进程intmain(){pid_tchild_pid;child_pid=fork();/*创建子进程*/if(child_pid>0){

sleep(60);/*父进程休眠60秒*/}else{exit(0);/*子进程立即退出*/}return0;}$ps-a-opid,ppid,s=state,command PIDPPIDstateCOMMAND 311628333S./zombie 31173116Z[zombie]<defunct> 313227018Rps-a-o…21进程终止父进程调用wait函数,对子进程进行处理。wait函数将阻塞程序,直到wait函数返回。22子进程退出的异步善后处理

pid_twait(int*stat_loc);pid_twaitpid(pid_tpid,int*stat_loc,intoptions);返回值:已结束运行的子进程id代表成功,-1代表失败WNOHANGvoidsigchld_handler(intsigno){…

/*等待已退出的所有子进程*/do{pid=waitpid(-1,&status,WNOHANG);}while(pid>0);}23EXIT系统调用系统调用exit的功能是终止发出调用的进程。它的声明格式如下:#include<stdlib.h>voidexit(intstatus);#include<unistd.h>void_exit(intstatus);

系统调用_exit立即终止发出调用的进程。所有属于该进程的文件描述符都关闭。该进程的所有子进程由进程1(进程init)接收,并对该进程的父进程发出一个SIGCHLD(子进程僵死)的信号。参数status作为退出的状态值返回父进程,该值可以通过系统调用wait来收集。返回状态码status只有最低一个字节有效。如果进程是一个控制终端进程,则SIGHUP信号将被送往该控制终端的前台进程。系统调用_exit从不返回任何值给发出调用的进程;也不刷新I/O缓冲,如果要自动完成刷新,可以用函数调用exit。exit为glibc库函数,它会先运行注册函数,也有可能会进行文件流的关闭操作,之后再调用_exit系统调用。24进程终止处理函数atexit()函数用于注册一个进程正常终止时要调用的函数,一个进程最多可注册32个终止处理函数。

#include<stdlib.h>intatexit(void(*function)(void));成功返回0,失败返回非0。参数为函数指针,此函数会在进程调用exit时调用。在main函数返回出,分别用return、exit(0)_exit(0),看其中的区别。_exit函数是不会调用注册函数的。252.信号信号是软件中断,用于向进程通知发生了某种事件,进程根据预先定义的信号处理程序对产生的事件进行响应信号提供了一种异步事件处理模型,即信号的产生时间对进程而言是随机的早期UNIX系统提供的信号不可靠,可靠信号机制在POSIX.1中进行了标准化26

Signalgeneratingexamples用户在终端键入CTRL+C,产生SIGINT中断信号硬件异常产生的信号,如SIGSEGV信号产生于非法内存地址引用kill函数允许一个进程向其他进程发送信号控制台kill命令允许Linux用户向进程发送消息,例如杀死某个进程27Kill命令和Kill函数

kill–l,列出当前linux支持的信号种类kill-ssignal_namepid,向进程pid发送信号kill[-signal_name]pidkill[-signal_number]pid#include<signal.h>intkill(pid_tpid,intsig);调用成功返回0,错误返回-1,并设置errno:EINVAL,信号非法或不被支持EPERM,调用者没有权限发送此信号ESRCH,信号接收方不存在(1)Kill命令(2)Kill函数28信号处理忽略信号收到信号然后直接丢弃。进程可以忽略大多数信号,但是SIGKILL和SIGSTOP信号除外捕获信号定义信号处理程序,当信号发生时执行该信号处理程序,SIGKILL和SIGSTOP除外

缺省处理每个信号都有一个默认的处理方式29SignalNames信号含义默认处理SIGABRT进程中止依赖具体实现SIGALRM闹钟到时异常终止SIGBUS访问内存对象未定义部分依赖具体实现SIGCHLD子进程退出、停止或者继续执行忽略SIGCONT使暂停进程继续继续SIGFPE算术操作错误,例如被0除依赖具体实现SIGHUP控制终端挂起异常终止SIGILL非法硬件指令依赖具体实现SIGINT终端中断,例如Ctrl+C异常终止SIGIO异步I/O忽略SIGKILL终止(不可捕获或忽略)异常终止SIGPIPE向无读进程管道写异常终止SIGQUIT终端退出(例如Ctrl-|)异常终止SIGSEGV非法内存引用终止SIGSTOP停止(不可捕获或忽略)停止SIGTERM终止异常终止SIGTSTP终端停止停止SIGTTIN后台读控制tty停止SIGTTOU后台写至控制tty停止SIGURG紧急数据忽略SIGUSR1用户定义信号1异常终止SIGUSR2用户定义信号2异常终止30#include<signal.h>intsigaction(intsignum,conststructsigaction*restrictact,structsigaction*restrictoldact);signum

,所要捕获或者忽略的信号act,代表新设置的信号处理结构体oldact,代表之前设置的信号处理结构体,可设置为NULLstructsigaction{void(*sa_handler)(int);/*信号处理函数*/sigset_tsa_mask;/*信号掩码,表示此信号处理函数中希望阻赛的信号*/intsa_flags;/*信号处理选项,如SA_RESTART*/void(*sa_sigaction)(int,siginfo_t*,void*);};信号处理SIG_DFLSIG_IGN31catchctrlc.cstructsigactionact;…intmain(intargc,char*argv[]){act.sa_handler=catchctrlc;act.sa_flags=0;

//清空信号掩码,设置SIGINT的信号处理函数if((sigemptys

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论