进程控制--进程的退出

什么是进程的退出?

进程退出无非三种情况

1.进程成功运行完毕,结果正确!

2.进程成功运行,结果不正确!

3.进程异常终止(程序崩溃!)

假如说我们一个进程成功运行完毕了,我们如何来判断我们的进程结果是否正确呢?

答案就是我们的main函数的返回值!

进程的退出码

以前我们写C语言的代码,int main函数里总是return 0,那么为什么是return 0呢?

int main()
{
    return 0;
}

我们不能返回其他的数字呢?  答案当然是可以的,我们想返回多少就返回多少。可是,在规定里,我们可不能随便返回一个值。

就像我们调用一个有返回值的函数,这个返回值是我们需要用到的,是不能随便返回的,那么mian函数的返回值是否也有意义呢?

当然是有意义的!!

我们先来看看这一串指令

 echo $?  指令是输出 最近运行完的一个进程的退出码。

当ls -al 正常运行的时候,我们通过echo $? 知道它的退出码是0。

而当我们运行ls -a -n -j -k -d  指令时,输出了   invalid option -- 'j'  无效指令 -j 命令行参数,而它这个进程的退出码是2。

这时候我们是否已经有了头绪了,每个进程的退出码都有它自己含义,成功一般退出码都是为0,而失败退出码就是其他数字。

这里我们来看一看Linux定义了哪些失败退出码。

 通过调用strerror查看。

0 : Success
1 : Operation not permitted
2 : No such file or directory
3 : No such process
4 : Interrupted system call
5 : Input/output error
6 : No such device or address
7 : Argument list too long
8 : Exec format error
9 : Bad file descriptor
10 : No child processes
11 : Resource temporarily unavailable
12 : Cannot allocate memory
13 : Permission denied
14 : Bad address
15 : Block device required
16 : Device or resource busy
17 : File exists
18 : Invalid cross-device link
19 : No such device
20 : Not a directory
21 : Is a directory
22 : Invalid argument
23 : Too many open files in system
24 : Too many open files
25 : Inappropriate ioctl for device
26 : Text file busy
27 : File too large
28 : No space left on device
29 : Illegal seek
30 : Read-only file system
31 : Too many links
32 : Broken pipe
33 : Numerical argument out of domain
34 : Numerical result out of range
35 : Resource deadlock avoided
36 : File name too long
37 : No locks available
38 : Function not implemented
39 : Directory not empty
40 : Too many levels of symbolic links
41 : Unknown error 41
42 : No message of desired type
43 : Identifier removed
44 : Channel number out of range
45 : Level 2 not synchronized
46 : Level 3 halted
47 : Level 3 reset
48 : Link number out of range
49 : Protocol driver not attached
50 : No CSI structure available
51 : Level 2 halted
52 : Invalid exchange
53 : Invalid request descriptor
54 : Exchange full
55 : No anode
56 : Invalid request code
57 : Invalid slot
58 : Unknown error 58
59 : Bad font file format
60 : Device not a stream
61 : No data available
62 : Timer expired
63 : Out of streams resources
64 : Machine is not on the network
65 : Package not installed
66 : Object is remote
67 : Link has been severed
68 : Advertise error
69 : Srmount error
70 : Communication error on send
71 : Protocol error
72 : Multihop attempted
73 : RFS specific error
74 : Bad message
75 : Value too large for defined data type
76 : Name not unique on network
77 : File descriptor in bad state
78 : Remote address changed
79 : Can not access a needed shared library
80 : Accessing a corrupted shared library
81 : .lib section in a.out corrupted
82 : Attempting to link in too many shared libraries
83 : Cannot exec a shared library directly
84 : Invalid or incomplete multibyte or wide character
85 : Interrupted system call should be restarted
86 : Streams pipe error
87 : Too many users
88 : Socket operation on non-socket
89 : Destination address required
90 : Message too long
91 : Protocol wrong type for socket
92 : Protocol not available
93 : Protocol not supported
94 : Socket type not supported
95 : Operation not supported
96 : Protocol family not supported
97 : Address family not supported by protocol
98 : Address already in use
99 : Cannot assign requested address
100 : Network is down
101 : Network is unreachable
102 : Network dropped connection on reset
103 : Software caused connection abort
104 : Connection reset by peer
105 : No buffer space available
106 : Transport endpoint is already connected
107 : Transport endpoint is not connected
108 : Cannot send after transport endpoint shutdown
109 : Too many references: cannot splice
110 : Connection timed out
111 : Connection refused
112 : Host is down
113 : No route to host
114 : Operation already in progress
115 : Operation now in progress
116 : Stale file handle
117 : Structure needs cleaning
118 : Not a XENIX named type file
119 : No XENIX semaphores available
120 : Is a named type file
121 : Remote I/O error
122 : Disk quota exceeded
123 : No medium found
124 : Wrong medium type
125 : Operation canceled
126 : Required key not available
127 : Key has expired
128 : Key has been revoked
129 : Key was rejected by service
130 : Owner died
131 : State not recoverable
132 : Operation not possible due to RF-kill
133 : Memory page has hardware error
134 : Unknown error 134
135 : Unknown error 135
136 : Unknown error 136
137 : Unknown error 137
138 : Unknown error 138
139 : Unknown error 139

可以看到Linux定义了多达133种退出码,0为进程运行结果成功!

所以,我们就可以得出结论,main函数的返回值是它运行后进程的退出码,反映了它自身的退出状态! 所以,main函数的返回值我们不能乱写,以后我们写大项目的时候,我们就可以从进程的退出码中推断错误!

进程退出的方式

1.return 

这是我们已经熟悉的不能再熟悉的方式了,这里就不用多讲了。

2.exit

以前我们写C语言程序的时候,也会用到exit,exit可以直接终止进程,并且带退出码。而它与return不同的地方就是,return如果在函数里面是终止这个函数,而exit如果在函数内使用,是终止整个程序!

 3._exit

_exit与exit有一些细微的差别,我们看看下面的代码就知道差别在哪了。

调用exit

调用_exit

 先看代码的区别,注意这里的打印hello world 没有加\n,我们分别调用了_exit和exit。

结果的区别,exit的运行结果输出了hello world,但是_exit的运行结果没有输出hello world。

这是为什么呢?

这是因为exit比_exit多了一些步骤,exit还冲刷了输出缓冲区

exit = _exit + 执行用户的清理函数 + 冲刷缓冲区、关闭流等

代码异常终止(程序崩溃!)

刚刚我们都是程序正常运行的例子,那么进程如果因为异常终止了,会发生什么呢?

 

 我们写一个会因为算术错误而导致进程终止的代码。

 这里我们使用 echo $? 却打印出了136,对比我们上面的退出码列表,136并不是退出码,那么这是什么呢?

首先要明确一点,我们希不希望代码崩溃?

肯定是不希望的,所以,这时候,如果进程因为异常终止了,它的退出码就没有了意义!!

总结

我们学习了进程控制中的关闭进程的操作,并且知道了return ,exit,_exit的区别,了解了进程异常终止的情况。 

猜你喜欢

转载自blog.csdn.net/fengjunziya/article/details/130764246