Linux环境编程–linux中的perror、exit、

perror:  #include<stdio.h>    #include<stdlib.h>定义函数  void perror(const char *s); perror ("open_port");函数说明  perror ( )用 来 将 上 一 个 函 数 发 生 错 误 的 原 因 输 出 到 标 准 错误 (stderr) 。参数 s 所指的字符串会先打印出,后面再加上错误原因字符串。此错误原因依照全局变量error 的值来决定要输出的字符串。    在库函数中有个error变量,每个error值对应着以字符串表示的错误类型。当你调用"某些"函数出错时,该函数已经重新设置了error的值。perror函数只是将你输入的一些信息和现在的error所对应的错误一起输出。exit:(#include <stdlib.h>) 在C语言的main函数中我们通常使用return (0);这样的方式返回一个值。但这是限定在非void情况下的,也就是非void main()这样的形式。    exit()通常是用在子程序中用来终结程序用的,使用后程序自动结束,跳出操作系统。    exit(0) 表示程序正常退出, exit(1)/exit(-1)表示程序异常退出。  exit() 结束当前进程/当前程序/,在整个程序中,只要调用 exit ,就结束。  但在如果把exit用在main内的时候无论main是否定义成void返回的值都是有效的,并且exit不需要考虑类型,exit(1)等价于return (1) 。   例如:   #include<stdlib.h>   int main()   {  exit (1);//等价于return (1);   }   exit()是一个函数 ,结束一个进程,它将删除进程使用的内存空间,同时把错误信息返回父进程,在父进程中wait系统调用将接受到此返回信息。

进程就好比人一样有其生命,我们通过fork()函数来创建一个进程,那么我们又是如何来中止进程呢。

进程退出

1.在Linux中任何让一个进程退出

进程退出表示进程即将结束。在Linux中进程退出分为了正常退出和异常退出两种。

1>正常退出

a. 在main()函数中执行return 。

b.调用exit()函数 #include <stdlib.h> void exit(int status)

c.调用_exit()函数 #include <unistd.h> void _exit(int status)

status 是一个整型的参数,可以利用这个参数传递进程结束时的状态。一般来说,0 表示正常结束;其他的数值表示出现了错误,进程非正常结束。在实际编程时,可以用 wait 系统调用接收子进程的返回值,从而针对不同的情况进行不同的处理

2>异常退出

a.调用about函数

b.进程收到某个信号,而该信号使程序终止。

Tiger-John说明:不管 是那种 退出方式,系统最终都会执行内核中的同一代码。这段代码用来关闭进程所用已打开的文件描述符,释放它所占用的内存和其他资源。

3>比较以上几种退出方式的不同点

(1)exit和return 的区别:

a.exit是一个函数,有参数。exit执行完后把控制权交给系统

b.return是函数执行完后的返回。renturn执行完后把控制权交给调用函数。

(2)exit和abort的区别:

a.exit是正常终止进程

b.about是异常终止。

现在我们重点了解exit()和_exit()函数

2.exit()和_exit()的学习

1>exit和_exit函数都是用来终止进程的。

当程序执行到exit或_exit时,系统无条件的停止剩下所有操作,清除包括PCB在内的各种数据结构,并终止本进程的运行。

2>exit在头文件stdlib.h中声明,而_exit()声明在头文件unistd.h中声明。 exit中的参数exit_code为0代表进程正常终止,若为其他值表示程序执行过程中有错误发生。

3>exit()和_exit()的区别:

a._exit()执行后立即返回给内核,而exit()要先执行一些清除操作,然后将控制权交给内核。

b. 调用_exit函数时,其会关闭进程所有的文件描述符,清理内存以及其他一些内核清理函数,但不会刷新流(stdin, stdout, stderr …). exit函数是在_exit函数之上的一个封装,其会调用_exit,并在调用之前先刷新流。

Tiger-John说明:

exit()函数与_exit()函数最大区别就在于exit()函数在调用exit系统之前要检查文件的打开情况,把文件缓冲区的内容写回文件。 由于Linux的标准函数库中,有一种被称作“缓冲I/O”的操作,其特征就是对应每一个打开的文件,在内存中都有一片缓冲区。每次读文件时,会连续的读 出若干条记录,这样在下次读文件时就可以直接从内存的缓冲区读取;同样,每次写文件的时候也仅仅是写入内存的缓冲区,等满足了一定的条件(如达到了一定数 量或遇到特定字符等),再将缓冲区中的内容一次性写入文件。这种技术大大增加了文件读写的速度,但也给编程代来了一点儿麻烦。比如有一些数据,认为已经写 入了文件,实际上因为没有满足特定的条件,它们还只是保存在缓冲区内,这时用_exit()函数直接将进程关闭,缓冲区的数据就会丢失。因此,要想保证数 据的完整性,就一定要使用exit()函数。

c . 通过一个函数实例来看看它们之间的区别:

函数实例1 : exit.c

1 #include<stdio.h>2 #include<stdlib.h>3 4 int main()5 {6 printf("using exit—-\n");7 printf("This is the content in buffer\n");8 exit(0);9 }

函数经过调试后

$ gcc exit.c -o exit$ ./exit

执行结果为:

using exit—-This is the content in buffer

函数实例2:_exit.c

1 #include<stdio.h>2 #include<unistd.h>3 4 int main(void)5 {6 printf("using _exit–\n");7 printf("This is the content in buffer");8 _exit(0);9 } 函数经过调试后

$ gcc _exit.c -o _exit$ ./_exit

执行结果为 :

using _exit–

Tiger-John说明:

1.printf函数就是使用缓冲I/O的方式,该函数在遇到“\n”换行符时自动的从缓冲区中将记录读出。所以exit()将缓冲区的数据写完后才退出,而_exit()函数直接退出。

2.大家也可以把函数实例2中的printf("This is the content in buffer");改为printf("This is the content in buffer\n")(即在printf中最后加一个\n看运行结果是什么,为什么会产生这样的结果呢?)

小知识

在一个进程调用了 exit 之后,该进程并不马上就完全消失,而是留下一个称为僵尸进程(Zombie)的数据结构。僵尸进程是一种非常特殊的进程,它几乎已经放弃了所有内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等信息供其他进程收集,除此之外,僵尸进程不再占有任何内存空间。

wait wait 函数是用于使父进程(也就是调用 wait 的进程)阻塞,直到一个子进程结束或者该进程接到了一个指定的信号为止。如果该父进程没有子进程或者他的子进程已经结束, wait则就会立即返回。#include <sys/types.h>#include <sys/wait.h>pid_t wait(int *status)waitpid waitpid 的作用和 wait 一样,但它并不一定要等待第一个终止的子进程,它还有若干选项,如可提供一个非阻塞版本的 wait 功能,也能支持作业控制。实际上 wait 函数只是 waitpid 函数的一个特例,在 Linux 内部实现 wait 函数时直接调用的就是 waitpid 函数。#include <sys/types.h>#include <sys/wait.h>pid_t waitpid(pid_t pid, int *status, int options)你在雨中行走,你从不打伞,你有自己的天空,它从不下雨。

Linux环境编程–linux中的perror、exit、

相关文章:

你感兴趣的文章:

标签云: