功能:
该函数类似于fork(),都是创建当前正在调用进程的子进程,有关细节、返回值以及可能出错的原因参考fork();该函数是一种特殊的克隆,在创建新的进程时不会去复制父进程中的页表信息(内存空间等);该函数创建完毕子进程后会挂起父进程,直到子进程终止或者调用exec系列函数为止,也就是保证了子进程先执行;在子进程终止/调用exec系列函数之前,子进程共享所有内存空间和父进程,包括栈区;子进程不能从当前函数中返回,也不能调用exit(),但是可以调用_exit();功能: 主要用于执行参数指定的文件指令;
参数: 第一个参数:字符串形式的路径名; 第二个参数:字符串形式的参数,一般指定具体的执行方式; 第三个参数:可变长参数;
返回值: success —- 无返回值,error —- -1;
如: 使用execl()执行ls -l命令,执行方式如下: execl("/bin/ls/","ls", "-l", NULL);
注意: vfork()本身没有太大的实际意义,一般与ecec系列的函数搭配使用,主要用于子进程执行与父进程完全不同代码段的场合中; 其中vfork()专门用于创建子进程,ecec系列函数专门用于跳转到全新的代码段中; 使用fork()也是可以与exec系列的函数进行搭配使用,但是效率没有vfork()高,但是最新的fork()内部由采用了写时拷贝技术来提高fork()的效率;
功能: 主要用于执行参数指定的shell命令,成功返回命令的退出状态信息,失败返回-1;
中断本质上就是停止当前程序的执行转而去执行新的程序或者处理意外情况的过程;
硬件中断、软件中断;
信号本质上就是一种软件中断,它既可以作为两个进程间通信的一种机制,更重要的是,信号总是可以终止一个程序的执行,它更多地被用于处理意外情况;
a. 信号是异步的,也就是说进程并不知道信号何时会到来; b. 进程既可以发送信号,也可以处理信号; c. 每个信号都有一个名字,用SIG开头;
kill -l:表示查看当前系统所支持的所有信号;
要求掌握的信号:
SIGINT信号2使用ctrl+c来产生该信号默认终止进程SIGQUIT信号3使用ctrl+\来产生该信号默认终止进程SIGKILL信号9使用kill -9来产生该信号默认终止进程在当前教学系统中所支持的信号范围是:1~64,不保证是连续的;
其中1~31之间的信号叫做不可靠信号,不支持排队,信号可能会丢失,也叫做非实时信号; 其中34~64之间的信号叫做可靠信号,支持排队,信号不会丢失,也叫做实时信号;
函数原型解析如下:
typedef void (*sighandler_t)(int); => typedef void (*)(int) sighandler_t; sighandler_t signal(int signum, sighandler_t handler); => void (*)(int) signal(int signum, void (*)(int) handler); => void (*)(int) signal(int signum, void (*handler)(int) ); => void (*signal(int signum, void (*handler)(int) ) )(int);=> signal首先是一个函数; 该函数有两个形参,一个是int类型,一个是函数指针类型; 该函数的返回值类型是一个函数指针类型 =>上述两个函数指针都是一个指向参数为int,返回值类型为void的函数的指针;
函数功能解析如下: 功能: 主要用于设置指定信号的处理方式; 参数: 第一个参数:具体的信号值 / 信号名称; 第二个参数:具体的处理方式; SIG_IGN - - - - - - - - - 忽略处理(ignore) SIG_DFL - - - - - - - - - 默认处理(default) 自定义函数的地址 - 自定义处理 返回值: success —- 之前的处理方式,error —- SIG_ERR;注意: SIGKILL这个信号只能采用默认处理方式进行处理,不能被用户捕捉,也就是不能用signal()去设置该信号的处理方式
(1)对于fork()创建的子进程来说,完全照搬父进程对信号的处理方式,父进程默认,子进程也默认处理;父进程忽略处理,则子进程也忽略处理;父进程自定义处理,子进程也自定义处理; (2)对于vfork()和execl()启动的子进程来说,父进程忽略,子进程也忽略;父进程默认,子进程也默认;但是父进程自定义,子进程却默认处理;
(1)采用键盘发送信号(只能发送部分特殊的信号) ctrl + c => 可以发送信号SIGINT 2 ctrl + \ => 可以发送信号SIGQUIT 3 … … (2)程序出错发送信号(只能发送部分特殊的信号) 段错误 => 可以发送信号SIGSEGV 11 (3)使用kill命令发送信号(所有信号都可以发送) kill -信号值 / 信号名称 进程号 => 表示给指定的进程发送指定的信号 (4)采用系统函数发送信号 kill() / raise() / alarm() / …
练习: vi 11kill.c文件,首先使用fork()创建子进程,然后子进程开始启动,并设置对信号40进行自定义处理,进入无限循环;父进程开始启动,判断子进程是否存在,若存在则用kill()给子进程发送信号40,并观察程序的执行结果;
明日预报: (1)信号的处理 (2)进程间的通信技术