exit()
/*
//Linux 系统库
#include <unistd.h>
void _exit(int status);
-参数:
status:进程退出时的状态信息,父进程挥手子进程的时候可以获取
// 标准C库
#include <stdlib.h>
void _Exit(int status);
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(){
printf("hello \n");
printf("world111");
exit(0);
printf("world222 \n");
return 0;
}
/*
carey@ubuntu:~/Linux/lesson12_exit$ ls
_exit.c exit.c
carey@ubuntu:~/Linux/lesson12_exit$ gcc exit.c -o exit
carey@ubuntu:~/Linux/lesson12_exit$ ./exit
hello
world111carey@ubuntu:~/Linux/lesson12_exit$
-分析,因为exit是标准C库, 在执行exit的时候会先刷新IO缓冲 关闭文件描述符, 然后再
调用_exit(), 所以会打印world111
*/
_exit()
/*
//Linux 系统库
#include <unistd.h>
void _exit(int status);
-参数:
status:进程退出时的状态信息,父进程挥手子进程的时候可以获取
// 标准C库
#include <stdlib.h>
void _Exit(int status);
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(){
printf("hello \n");
printf("world111 \n"); //(1)
//printf("world111"); (2)
//exit(0);
_exit(0);
printf("world222 \n");
return 0;
}
/*
//
(1):
carey@ubuntu:~/Linux/lesson12_exit$ gcc exit.c -o exit
carey@ubuntu:~/Linux/lesson12_exit$ ./exit
hello
world111
-分析:因为printf是标准C库的函数,在IO时有缓冲区,\n之后会刷新缓冲区,所以会打印。
(2):
carey@ubuntu:~/Linux/lesson12_exit$ gcc exit.c -o exit
carey@ubuntu:~/Linux/lesson12_exit$ ./exit
hello
-分析:同上,没有\n所以数据没有刷新到系统, 所以没打印。
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(){
pid_t pid = fork();
if(pid > 0){
printf("PARENT : pid = %d, ppid = %d \n", getpid(), getppid());
}else if(pid == 0){
sleep(1);
printf("child : pid = %d, ppid = %d \n", getpid(), getppid());
}
for(int i=0; i<3; i++){
printf("i = %d, pid = %d, ppid = %d \n", i, getpid(), getppid());
}
return 0;
}
/*
carey@ubuntu:~/Linux/lesson12_exit$ gcc orphan.c -o orphan
carey@ubuntu:~/Linux/lesson12_exit$
carey@ubuntu:~/Linux/lesson12_exit$ ./orphan
child : pid = 3422, ppid = 3421
PARENT : pid = 3421, ppid = 2141
i = 0, pid = 3421, ppid = 2141
i = 1, pid = 3421, ppid = 2141
i = 2, pid = 3421, ppid = 2141
carey@ubuntu:~/Linux/lesson12_exit$ i = 0, pid = 3422, ppid = 1
i = 1, pid = 3422, ppid = 1
i = 2, pid = 3422, ppid = 1
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(){
pid_t pid = fork();
if(pid > 0){
while(1){
printf("PARENT : pid = %d, ppid = %d \n", getpid(), getppid());
sleep(1);
}
}else if(pid == 0){
printf("child : pid = %d, ppid = %d \n", getpid(), getppid());
}
for(int i=0; i<3; i++){
printf("i = %d, pid = %d, ppid = %d \n", i, getpid(), getppid());
}
return 0;
}
/*
carey@ubuntu:~/Linux/lesson12_exit$ gcc Zomble.c -o zomble
carey@ubuntu:~/Linux/lesson12_exit$ ls
exit _exit _exit.c exit.c orphan orphan.c zomble Zomble.c
carey@ubuntu:~/Linux/lesson12_exit$ ./zomble
PARENT : pid = 3472, ppid = 2141
child : pid = 3473, ppid = 3472
i = 0, pid = 3473, ppid = 3472
i = 1, pid = 3473, ppid = 3472
i = 2, pid = 3473, ppid = 3472
PARENT : pid = 3472, ppid = 2141
PARENT : pid = 3472, ppid = 2141
PARENT : pid = 3472, ppid = 2141
PARENT : pid = 3472, ppid = 2141
carey 3472 0.0 0.0 4512 724 pts/1 S+ 18:32 0:00 ./zomble
carey 3473 0.0 0.0 0 0 pts/1 Z+ 18:32 0:00 [zomble] <defunct>
*/
/*
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *wstatus);
pid_t waitpid(pid_t pid, int *wstatus, int options);
-功能:
等待任意一个子进程结束,如果任意一个子进程结束了,次函数会回收子进
-参数: int *wstatus
进程退出时的状态信息,传入的是一个int类型的地址,传出参数。
-返回值:
-成功:返回被回收的子进程的id
-失败:-1(所以的子进程都结束,调用函数失败)
调用wait(),函数会被挂起(阻塞),直到他的一个子进程退出或者收到一个不能被忽略的信号时
才被唤醒(继续执行)。
如果没有子进程了,函数立刻返回(-1),
如果子进程都结束了,函数立刻返回(-1),
并且资源都被回收。
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
pid_t pid;
//创建5个子进程
for(int i=0; i<5; i++){
pid = fork();
if(pid == 0){
break; //子进程不再产生子进程
}
}
if(pid > 0){
//Parent
while(1){
printf("PARENT : pid = %d \n", getpid());
int st;
int ret = wait(&st);
if(ret == -1){
break;
}
if(WIFEXITED(st)){
//是否正常退出
printf("退出的状态码:%d \n", WEXITSTATUS(st));
}
if(WIFSIGNALED(st)){
//是否异常终止
printf("被哪个信号中止:%d \n", WTERMSIG(st));
}
printf("ret = %d \n", ret);
sleep(1);
}
}else if(pid == 0){
//child
while(1){ //不循环为1, 有循环为2
printf("child : pid = %d \n", getpid());
sleep(2);
}
exit(0);
}
return 0;
}
# 1 运行结果
carey@ubuntu:~/Linux/lesson13_wait$ gcc wait.c -o wait
carey@ubuntu:~/Linux/lesson13_wait$ ./wait
child : pid = 4306
child : pid = 4307
child : pid = 4309
child : pid = 4308
child : pid = 4310
PARENT : pid = 4305
退出的状态码:0
ret = 4306
PARENT : pid = 4305
退出的状态码:0
ret = 4307
PARENT : pid = 4305
退出的状态码:0
ret = 4308
PARENT : pid = 4305
退出的状态码:0
ret = 4309
PARENT : pid = 4305
退出的状态码:0
ret = 4310
PARENT : pid = 4305
#2 运行结果
carey@ubuntu:~/Linux/lesson13_wait$ gcc wait.c -o wait
carey@ubuntu:~/Linux/lesson13_wait$ ./wait
child : pid = 4330
child : pid = 4329
child : pid = 4332
PARENT : pid = 4328
child : pid = 4333
child : pid = 4331
child : pid = 4330
...
# 另开窗口 杀死进程
carey@ubuntu:~/Linux$ kill -9 4329
carey@ubuntu:~/Linux$ kill -9 4330
carey@ubuntu:~/Linux$ kill -9 4331
carey@ubuntu:~/Linux$ kill -9 4332
carey@ubuntu:~/Linux$ kill -9 4333
#结果:
child : pid = 4330
child : pid = 4333
被哪个信号中止:9
ret = 4330
child : pid = 4331
child : pid = 4332
child : pid = 4333
PARENT : pid = 4328
child : pid = 4331
child : pid = 4332
child : pid = 4333
被哪个信号中止:9
ret = 4331
PARENT : pid = 4328
child : pid = 4332
child : pid = 4333
被哪个信号中止:9
ret = 4332
PARENT : pid = 4328
child : pid = 4333
被哪个信号中止:9
ret = 4333
PARENT : pid = 4328
/*
#include <sys/types.h>
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int *wstatus, int options);
-功能:
回收指定进程号的子进程,可以设置是否阻塞。
-参数:
-pid :
-pid > 0 : 某个子进程的 pid
-pid = 0 : 回收当前进程组的所有子进程 其次
-pid = -1: 回收所有的子进程,相当于wait() 最常用
-pid < -1: 某个进程组的组id的绝对值,回收指定进程组中的子进程
-int *wstatus
进程退出时的状态信息,传入的是一个int类型的地址,传出参数。
-返回值:
>0: 返回被回收的子进程的id
=0: options=WNOHANG, 表示还有子进程活着
-1: 错误或者没有子进程
调用wait(),函数会被挂起(阻塞),直到他的一个子进程退出或者收到一个不能被忽略的信号时
才被唤醒(继续执行)。
如果没有子进程了,函数立刻返回(-1),
如果子进程都结束了,函数立刻返回(-1),
并且资源都被回收。
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
pid_t pid;
//创建5个子进程
for(int i=0; i<5; i++){
pid = fork();
if(pid == 0){
break; //子进程不再产生子进程
}
}
if(pid > 0){
//Parent
while(1){
printf("PARENT : pid = %d \n", getpid());
int st;
int ret = waitpid(-1, &st, 0);
if(ret == -1){
break;
}
if(WIFEXITED(st)){
//是否正常退出
printf("退出的状态码:%d \n", WEXITSTATUS(st));
}
if(WIFSIGNALED(st)){
//是否异常终止
printf("被哪个信号中止:%d \n", WTERMSIG(st));
}
printf("ret = %d \n", ret);
sleep(1);
}
}else if(pid == 0){
//child
while(1){
printf("child : pid = %d \n", getpid());
sleep(2);
}
exit(0);
}
return 0;
}