进程创建
fork函数
fork函数是Linux系统提供的接口,其功能就是创建子进程。
既调用fork函数,系统就自动为我们创建好了子进程。
代码语言:javascript
AI代码解释
#include<unistd.h> pid_t fork(); 其中pid_t是Linux中的数据类型,相当于int,即为整型fork的返回值有两个,对于父进程:返回子进程的pid,对于子进程:返回0。
代码语言:javascript
AI代码解释
#include <stdio.h> #include <unistd.h> int main() { pid_t pid = fork(); if(pid<0) { printf("创建失败"); } else if(pid == 0) { //子进程 printf("我是一个子进程:%d,这是我的父进程:%d\n",getpid(),getppid()); } else if(pid > 0) { printf("我是一个父进程:%d,这是我的父进程:%d\n",getpid(),getppid()); } }对于fork原理的详细介绍可参考【Linux】初见,进程概念-CSDN博客中的第四节“如何创建进程”,这里面有超级详细的介绍!
fork的用法
一个父进程希望复制自己,使父子进程同时执行不同的代码段。e.g. 父进程等待客户端响应,生成子进程处理请求。
一个进程想要执行多个不同的代码。e.g. 生成子进程调用exec函数。
fork失败原因
系统中的进程太多了
用户的进程数量超过了限制
进程终止
进程终止的本质就是进程结束,系统释放资源:释放进程申请的相关数据结构和对应的代码与数据
进程退出的场景
1.代码运行完毕,结果正确(退出码为0)
2.代码运行完毕,结果不正确(退出码为非0)
3.代码异常终止(进程接收到型号终止,退出码无意义)
进程退出方法
正常退出:
1.从main函数返回
2.调用exit
3._exit
异常退出:
信号终止
退出码
退出码可以告诉我们进程终止时的状态,0代表执行成功,非0则代表不成功。
非0的退出码中,一个值对应一个错误原因。可以使用strerror函数获取退出码对应的信息。
代码语言:javascript
AI代码解释
#include <stdio.h> #include<string.h> int main() { for(int i=0;i<200;i++) { printf("%d -> %s\n",i,strerror(i)); } }代码语言:javascript
AI代码解释
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使用echo $?,可以打印出最近一个程序的退出码。
退出码是进程的性质之一,所以退出码会保存到进程的PCB中。
_exit函数
代码语言:javascript
AI代码解释
#include<unistd.h> void _exit(int status); 在任何地方调用_exit函数,都会让当前进程结束 并以给定的值作为退出码退出exit函数
代码语言:javascript
AI代码解释
#include<unistd.h> void exit(int status); 与_exit函数功能类似 都是以指定的退出码,退出当前进程区别
_exit函数系统调用,而exit是C语言提供。
使用exit函数退出时,会进行缓冲区的刷新。反之_exit则不会。
举个例子说明:
程序结束刷新缓冲区,信息打印在屏幕上,反之没有信息打印。
感兴趣的朋友可以看看这篇文章,这里有详细的缓冲区刷新介绍【Linux】LInux下第一个程序:进度条-CSDN博客
代码语言:javascript
AI代码解释
#include <stdio.h> #include<string.h> #include<unistd.h> int main() { printf("yuzuriha"); sleep(1); exit(0); }代码语言:javascript
AI代码解释
#include <stdio.h> #include<string.h> #include<unistd.h> int main() { printf("yuzuriha"); sleep(1); _exit(0); }进程等待
进程等待的必要性
1.之前我们讲过子进程的退出后,子进程回进入僵尸状态,必须要被父进程回收才行。若子进程一直没有被父进程回收,就会一直处于僵尸状态,进而造成内存泄漏。
2.进程被创造出来执行任务,结果如何,是成功、失败还是异常,这是父进程要得知的必要信息。
所以回收子进程是必要的,父进程通过进程等待的方式,回收子进程进程资源、获取子进程的退出信息。
进程等待的方法
wait方法
代码语言:javascript
AI代码解释
#include<sys/types.h> #include<sys/wait.h> pid_t wait(int* status); 返回值:等待成功返回对应的子进程pid,失败则返回-1 参数status:为输出型参数,可以获取子进程的退出码 若不需要,可以传NULL忽略这个参数waitpid函数
代码语言:javascript
AI代码解释
#include<sys/types.h> #include<sys/wait.h> pid_ t waitpid(pid_t pid, int *status, int options);下面详细介绍一下每一个参数:
pid_t pid
参数pid:-1,表示可以等待任意一个子进程。
参数pid:>0,表示只能等待当前这个进程的子进程。
status
如上面所讲,status是一个输出型参数,由操作系统填充,我们可以通过status获取进程状态。
status并不是一个简单的整型,细节如下:
1.status是一个低16位有效的int,通过位划分存储子进程的信息 2.正常终止的情况下:低7位全为0,15~8存放退出码。 获取退出码:WEXITSTATUS(status)3.非正常退出:退出码无意义,第7位存放标志,6~0存放信号编号判断一个进程是否位正常退出:WIFEXITED(status),正常为真。
options
options的默认值是0,表示阻塞等待。
options为:WNOHANG时表示非阻塞等待。
简而言之,阻塞等待就是等待子进程结束的过程中,父进程不能运行。而非阻塞等待,就是等待过程中父进程可以执行自己的代码。
当参数为:WNOHANG时,waitpid会进行非阻塞轮询。等待结束,返回>0(pid);本次调用结束,但子进程还没有退出,返回0;调用失败,返回<0;。
www.dongchedi.com/article/7600082197533737496
www.dongchedi.com/article/7600081551585788478
www.dongchedi.com/article/7600080627626836505
www.dongchedi.com/article/7600076432072786494
www.dongchedi.com/article/7600077785914540569
www.dongchedi.com/article/7600076654119207449
www.dongchedi.com/article/7600076084386021950
www.dongchedi.com/article/7600077060547084862
www.dongchedi.com/article/7600075783578763800
www.dongchedi.com/article/7600075136489783833
www.dongchedi.com/article/7600073513009529369
www.dongchedi.com/article/7600074164837761598
www.dongchedi.com/article/7600073368318542361
www.dongchedi.com/article/7600073001341993534
www.dongchedi.com/article/7600073974269329982
www.dongchedi.com/article/7600074487064805912
www.dongchedi.com/article/7600073227586683454
www.dongchedi.com/article/7600069482082386457
www.dongchedi.com/article/7600071292192260670
www.dongchedi.com/article/7600069215726977561
www.dongchedi.com/article/7600071094875537982
www.dongchedi.com/article/7600070748635939353
www.dongchedi.com/article/7600069587262308926
www.dongchedi.com/article/7600069571290087961
www.dongchedi.com/article/7600069625426395673
www.dongchedi.com/article/7600069065444704793
www.dongchedi.com/article/7600070228240138814
www.dongchedi.com/article/7600069571290645017
www.dongchedi.com/article/7600068352702448153
www.dongchedi.com/article/7600069299780813374
www.dongchedi.com/article/7600070076465070654
www.dongchedi.com/article/7600070076464808510
www.dongchedi.com/article/7600069722168148504
www.dongchedi.com/article/7600068030437032510
www.dongchedi.com/article/7600068903506723352
www.dongchedi.com/article/7600069051742044697
www.dongchedi.com/article/7600067161435980313
www.dongchedi.com/article/7600067215119450648
www.dongchedi.com/article/7600066283626922521
www.dongchedi.com/article/7600067654162367000
www.dongchedi.com/article/7600067338523640382
www.dongchedi.com/article/7600061876546290238
www.dongchedi.com/article/7600062394333037081
www.dongchedi.com/article/7600064751125168702
www.dongchedi.com/article/7600062857611199000
www.dongchedi.com/article/7600064428301877822
www.dongchedi.com/article/7600065673062187544
www.dongchedi.com/article/7600061447326286360
www.dongchedi.com/article/7600064204875727422
www.dongchedi.com/article/7600063689303409214
www.dongchedi.com/article/7600063881645883928
www.dongchedi.com/article/7600061290274980376
www.dongchedi.com/article/7600063037474652696
www.dongchedi.com/article/7600058391884956222
www.dongchedi.com/article/7600058999849091609
www.dongchedi.com/article/7600054609557619224
www.dongchedi.com/article/7600058346296918590
www.dongchedi.com/article/7600062930226741822