wait后面的代码执行吗_javascript代码

wait后面的代码执行吗_javascript代码wait和waitpid详解及代码示例1.父子进程处理历史及父进程处理方法2.wait2.1wait功能2.2wait接口2.3wait原理2.3.1wait源码实现2.4wait参数:2.5wait返回值:2.6wait代码示例3.waitpid3.1waitpid功能3.2waitpid接口3.3waitpid原理3.4waitpid参数:3.5waitpid返回值:3.6waitpid代码示例参考1.父子进程处理历史及父进程处理方法

wait后面的代码执行吗_javascript代码"

wait 和 waitpid 详解及代码示例

  • 1. 父子进程处理历史及父进程处理方法
  • 2. wait
    • 2.1 wait 功能
    • 2.2 wait 接口
    • 2.3 wait 原理
      • 2.3.1 wait 源码实现
    • 2.4 wait 参数:
    • 2.5 wait 返回值:
    • 2.6 wait 代码示例
  • 3. waitpid
    • 3.1 waitpid 功能
    • 3.2 waitpid 接口
    • 3.3 waitpid 原理
    • 3.4 waitpid 参数:
    • 3.5 waitpid 返回值:
    • 3.6 waitpid 代码示例
  • 参考

1. 父子进程处理历史及父进程处理方法

进程用wait和waitpid函数清理僵尸进程,父进程可以阻塞等待子进程结束,也可以非阻塞地查询是否有子进程结束等待清理(也就是轮询的方式)。
采用第一种方式,父进程阻塞了就不能处理自己的工作了;
采用第二种方式,父进程在处理自己的工作的同时还要记得时不时地轮询一下,程序实现复杂。

其实,子进程在终止时会给父进程发SIGCHLD信号,该信号的默认处理动作是忽略,父进程可以自定义SIGCHLD信号的处理函数,这样父进程只需专心处理自己的工作,不必关心子进程了,子进程终止时会通知父进程,父进程在信号处理函数中调用wait清理子进程即可。

事实上,由于UNIX的历史原因,要想不产生僵尸进程还有另外一种办法:父进程调用sigaction将SIGCHLD的处理动作置为SIG_IGN,这样fork出来的子进程在终止时会自动清理掉,不会产生僵尸进程,也不会通知父进程。系统默认的忽略动作和用户用sigaction函数自定义的忽略通常是没有区别的,但这是一个特例。此方法对于Linux可用,但不保证在其它UNIX系统上都可用。请编写程序验证这样做不会产生僵尸进程。

2. wait

2.1 wait 功能

简单点就是:销毁子进程。

wait()就是得到子进程的返回码,等于就是为子进程“收尸”,否则子进程会变僵尸进程

2.2 wait 接口

pid_t wait(int *status)  

2.3 wait 原理

进程一旦调用了wait,就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸的子进程,wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。

2.3.1 wait 源码实现

wait就是经过包装的waitpid

察看<内核源码目录>/include/unistd.h文件349-352行就会发现以下程序段:
     
static inline pid_t wait(int * wait_stat)   
{  
  return waitpid(-1,wait_stat,0);
}

2.4 wait 参数:

参数status用来保存被收集进程退出时的一些状态,它是一个指向int类型的指针。但如果我们对这个子进程是如何死掉的毫不在意,只想把这个僵尸进程消灭掉,(事实上绝大多数情况下,我们都会这样想),我们就可以设定这个参数为NULL,就象下面这样:

pid = wait(NULL);

2.5 wait 返回值:

如果成功,wait会返回被收集的子进程的进程ID
如果调用进程没有子进程,调用就会失败,此时wait返回-2,同时errno被置为ECHILD。

2.6 wait 代码示例

#include <stdio.h>
#include <errno.h>
#include <unistd.h>

int main(int argc, char* argv[]){
	int childpid;
	pid_t pid;

	pid = fork();
	if(pid > 0)
	{
		printf("parent execl done\n");
		wait(NULL);
	}else if(0 == pid)
	{
		execl("/bin/ls", "ls", "-l", NULL);
		printf("pid execl done\n");
	}else{
		printf("error pid < 0 \n");
	}
	printf("exiting...\n");
	return 0;
}

结果:

[root@glusterfs home]# gcc test.c 
[root@glusterfs home]# ./a.out 
parent execl done
total 24
-rwxr-xr-x 1 root root 8632 Dec  4 09:50 a.out
-rw-r--r-- 1 root root  439 Dec  4 09:50 test.c
exiting...
[root@glusterfs home]# 

3. waitpid

3.1 waitpid 功能

  1. 从本质上讲,系统调用waitpid和wait的作用是完全相同的。

  2. 但waitpid多出了两个可由用户控制的参数pid和options,从而为我们编程提供了另一种更灵活的方式。

3.2 waitpid 接口

pid_t waitpid(pid_t pid,int *status,int options) 

3.3 waitpid 原理

从本质上讲,系统调用waitpid和wait的作用是完全相同的
就是如下:
进程一旦调用了waitpid,就立即阻塞自己,由waitpid自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸的子进程,waitpid就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,waitpid就会一直阻塞在这里,直到有一个出现为止。

3.4 waitpid 参数:

1. status 同上

2. pid: 从参数的名字pid和类型pid_t中就可以看出,这里需要的是一个进程ID。
但当pid取不同的值时,在这里有不同的意义。     
	2.1 pid>0时,只等待进程ID等于pid的子进程,不管其它已经有多少子进程运行结束退出了,只要指定的子进程还没有结束,waitpid就会一直等下去。
	2.2 pid=-1时,等待任何一个子进程退出,没有任何限制,此时waitpid和wait的作用一模一样。   
	2.3 pid=0时,等待同一个进程组中的任何子进程,如果子进程已经加入了别的进程组,waitpid不会对它做任何理睬。
	2.4 pid<-1时,等待一个指定进程组中的任何子进程,这个进程组的ID等于pid的绝对值。   
	
3. options: options提供了一些额外的选项来控制waitpid
目前在Linux中只支持 WNOHANG 和 WUNTRACED 两个选项,这是两个常数,可以用"|"运算符把它们连接起来使用

如果使用了WNOHANG参数调用waitpid,即使没有子进程退出,它也会立即返回,不会像wait那样永远等下去。
而WUNTRACED参数,由于涉及到一些跟踪调试方面的知识,加之极少用到

可以通过用常量WNOHANG和WUNTRACED的不同组合来设置options,修改默认行为:

	1. WNOHANG :如果没有等待集合中的任何子进程终止,那么就立即返回(返回值为0)0
	2. WUNTRACED :挂起调用进程的执行,直到等待集合中的一个进程变成终止的或者被暂停。
			返回的PID为导致返回的终止或暂停了进程的PID。
	3. WNOHANG | WUNTRACED:立即返回,如果没有等待集合中的任何子进程停止或终上,
			那么返回值为0,或者返回值等于那个被停止或者终止子进程的PID

示例:

ret=waitpid(-1,NULL,WNOHANG | WUNTRACED);   

如果我们不想使用它们,也可以把options设为0,如:

ret=waitpid(-1,NULL,0); 

3.5 waitpid 返回值:

waitpid的返回值比wait稍微复杂一些,一共有3种情况:

1. 当正常返回的时候,waitpid返回收集到的子进程的进程ID;
2. 如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0;      
3. 如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在;
   如果调用进程没有子进程,那么waitpid返回-1,并且设置errno为ECHILD。
   如果waitpid函数被一个信号中断,那么它返回-1,并设置为EINTR。

3.6 waitpid 代码示例

#include <stdio.h>
#include <errno.h>
#include <unistd.h>

int main(int argc, char* argv[]){
		int childpid;
		pid_t pid;

		pid = fork();
		if(pid > 0)
		{
				printf("parent execl done\n");
				waitpid(-1,0,0);
		}else if(0 == pid)
		{
				execl("/bin/ls", "ls", "-l", NULL);
				printf("pid execl done\n");
		}else{
				printf("error pid < 0 \n");
		}
		printf("exiting...\n");
		return 0;
}

结果:

[root@glusterfs home]# gcc waitpid.c 
[root@glusterfs home]# ./a.out 
parent execl done
total 28
-rwxr-xr-x 1 root root 8640 Dec  7 14:29 a.out
-rw-r--r-- 1 root root  374 Dec  7 14:29 waitpid.c
exiting...
[root@glusterfs home]#

参考

https://www.cnblogs.com/LUO77/p/5804436.html

今天的文章wait后面的代码执行吗_javascript代码分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/58378.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注