Chinaunix首页 | 论坛 | 博客
  • 博客访问: 247392
  • 博文数量: 53
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 380
  • 用 户 组: 普通用户
  • 注册时间: 2013-08-01 10:17
文章分类

全部博文(53)

文章存档

2013年(53)

分类: C/C++

2013-09-06 20:33:47

1、一个进程正常结束:

(1)return

(2)exit

(3)_exit和_Exit

(4)进程的最后一个线程使用return

(5)进程的最后一个线程使用phread_exit

2、一个异常进程结束:

(1)abort

(2)signal

(3)cancellation request ,最后一个线程被取消

3、当一个进程结束时,它的父进程需要知道它是如何结束的,于是需要得到子进程的termination status,parent process可以通过wait 和waitpid两个函数得到。

(1)当parent process 先于child process结束

init process(ID is 1)接手它的child process,kernel搜索所有的进程,看看结束的进程是否是正在运行的进程的父进程,如果是,则将它们的父进程改为init process。

(2)子进程先于父进程结束

kernle 保留了所有将要结束的进程的信息,如:process ID,termnation status,a mount of CPU time,这样的话,parent process可以通过wait和waitpid得到termination status。

(3)当一个进程的父进程变成init process时,发生了什么?

无论何时child process结束,init调用wait函数得到termination status。init进程总是可以获得子进程的终止状态。

4、wait和waitpid

(1)当调用这两个函数时,可能发生三种情况:

(1)block——如果它的子进程全部都在运行。
(2)立即返回child process的termination status——如果有子进程终止。

(3)返回error——如果没有子进程。

# include

pid_t wait (int *statloc);

pid_t waitpid (pid_t pid, int *statloc, int options);

(2)两者的区别

(1)wait可能阻塞caller直到一个子进程终止,而waitpid则可以通过选项不会阻塞。

(2)waitpid并不等待第一个终止的进程,它有选项可以控制它所等待的进程。

(3)对于得到的ternimation status我们可以通过四个macos来区分:

(1)WIFEXITED(status) //正常终止

(2)WIFSIGNALED(status) //异常终止,获取异常信号

(3)WIFSTOPPED(status)

(4)WIFCONTINUED(status)

(4)waitpid根据pid的不同来获取不同的进程termination status。

(1)waitpid可以wait某个特定的process,而wait则是任何的terminated child

(2)waitpid是nonblockling //可以使用选项控制为非阻塞

(3)waitpid支持WUNTRACED和WCONTINUED //waitpid支持任务控制

 

 

 

 

 

 

备注:当子进程结束的时候,父进程会收到SIGCHLD通知 2.进程可以调用wait/waitpid等待此Signal.为了减少僵尸进程的产生,我们可以采用waitpid而减少wait的使用,虽然僵尸进程可以由init回收

今天看了unix网络编程中的关于wait和waitpid的区别,它采用的验证例子是客户/服务器的连接问题

1.当子进程结束的时候,父进程会收到SIGCHLD通知

2.进程可以调用wait/waitpid等待此Signal

    a.当所有子进程都在执行的时候,会block

    b.当某个子进程中止,成为zombie的时候,立刻返回

    c.如果没有任何子进程,则返回错误

以前曾经学过这两函数的使用,但是没有什么例子可以验证,今天巧遇网络编程,就把这两个函数重新温习一下:

pid_t wait(int *stat_loc);

pid_t waitpid(pid_t pid, int *stat_loc, int options);

两个函数的不同在于wait会令调用者阻塞直至某个子进程终止而waitpid则可以通过设置一个选项来设置为非阻塞,另外waitpid并不是等待第一个结束的进程而是等待参数中pid指定的进程。
两 个函数中的变量statloc是一个指向int型数据的指针。如果此变量不是NULL,则结束的进程的termination status会被保存在statiloc所指向的内存的区域;如果我们不关心termination status,则可以把statloc置为NULL。

waitpid函数:

如 果一个进程有若干个子进程, 那么只要有一个子进程返回, wait就返回. 如果要等待一个指定的子进程, 有两种方法. 第一个种, 早期的UNIX必须调用wait, 然后把返回的pid和期望pid做比较, 如果不是期望的, 把该pid保存起来, 继续调用wait, 直到进程终止. 第二种是使用waitpid.

#include

#include

pid_t waitpid(pid_t pid, int *statloc, int options);

函数返回: 若成功则为进程ID, 若出错则为-1.

参数说明:

pid:


pid == -1 等待任一子进程. 这个时候waitpid与wait等效.
pid > 0     等待其ID与pid相等的子进程.
pid == 0 等待其组ID与调用进程的组ID的任一子进程.
pid < -1    等待其组ID等于pid绝对值的任一子进程.

对于waitpid函数, 如果指定的进程或进程组不存在, 或者调用进程没有子进程都会出错.

options:

这个一参数可以让我们进一步控制waitpid的操作, 此参数或者是0, 或者是下列的逐位或常数之一:

WNOHANG: 若由pid指定的子进程并不立即可用, 则waitpid不阻塞, 此时其返回值为0.

WUNTRACED: 若某实现支持作业控制, 则由pid指定的任一子进程状态已暂停, 且其状态自暂停以来还                       未报告过, 则返回其状态. WIFSTOPPED宏确定返回值是否对应于一个暂停子进程.

    下面我们来具体看看wait和waitpid在网络编程中使用的区别:

wait和waitpid的区别 - kinggsc - kinggsc的博客void sig_chld(int signo)

wait和waitpid的区别 - kinggsc - kinggsc的博客wait和waitpid的区别 - kinggsc - kinggsc的博客wait和waitpid的区别 - kinggsc - kinggsc的博客{

wait和waitpid的区别 - kinggsc - kinggsc的博客   pid_t pid;

wait和waitpid的区别 - kinggsc - kinggsc的博客   int stat;

wait和waitpid的区别 - kinggsc - kinggsc的博客   pid = wait(&stat);

wait和waitpid的区别 - kinggsc - kinggsc的博客   printf("child %d terminated \n",pid);

wait和waitpid的区别 - kinggsc - kinggsc的博客   return;

wait和waitpid的区别 - kinggsc - kinggsc的博客}

wait和waitpid的区别 - kinggsc - kinggsc的博客

wait和waitpid的区别 - kinggsc - kinggsc的博客void sig_chld(int signo)

wait和waitpid的区别 - kinggsc - kinggsc的博客wait和waitpid的区别 - kinggsc - kinggsc的博客wait和waitpid的区别 - kinggsc - kinggsc的博客{

wait和waitpid的区别 - kinggsc - kinggsc的博客   pid_t pid;

wait和waitpid的区别 - kinggsc - kinggsc的博客   int stat;

wait和waitpid的区别 - kinggsc - kinggsc的博客   while((pid = waitpid(-1,&stat,WNOHANG))>0)

wait和waitpid的区别 - kinggsc - kinggsc的博客   printf("child %d terminated \n",pid);

wait和waitpid的区别 - kinggsc - kinggsc的博客   return;

wait和waitpid的区别 - kinggsc - kinggsc的博客}

wait和waitpid的区别 - kinggsc - kinggsc的博客

上面是两段不同的信号处理函数,它们的结果可能相差很多的,下面我们就来看看有哪些区别:

首先我们看看用wait函数产生的效果:

1、下面的输出是在启动客户端和服务器端程序后的ps输出

备注:在客户端程序中,我们连续产生5个服务器连接进程,所以一共6个waitsrv进程

wait和waitpid的区别 - kinggsc - kinggsc的博客

2、下面是在客户端输入ctrl+d后的服务器端输出和ps查询后的结果

wait和waitpid的区别 - kinggsc - kinggsc的博客

wait和waitpid的区别 - kinggsc - kinggsc的博客

我们从上面可以看出利用wait的一个致命的缺点就是只能回收一个子进程,其他的进程由于没有得到回收而变成僵尸进程

下面我们来看看利用waitpid函数的输出结果:

   1、启动服务器端和客户端后的ps输出

wait和waitpid的区别 - kinggsc - kinggsc的博客

2、在客户端输入ctrl+d后的服务器端输出和ps的结果

wait和waitpid的区别 - kinggsc - kinggsc的博客

wait和waitpid的区别 - kinggsc - kinggsc的博客

   我们可以发现所有服务器的子进程在接受到客户端输入的EOF后,都被回收了!

   由此,我们可以发现,为了减少僵尸进程的产生,我们可以采用waitpid而减少wait的使用,虽然僵尸进程可以由init回收

   以上的例子程序是采用的unix网络编程中的例子,在此代码就不再详细列出了!

 

 

 

 

 

 

 

 

 sleep和wait的区别

1、这两个方法来自不同的类分别是,sleep来自Thread类,和wait来自Object类。

sleep是Thread的静态类方法,谁调用的谁去睡觉,即使在a线程里调用了b的sleep方法,实际上还是a去睡觉,要让b线程睡觉要在b的代码中调用sleep。


2、最主要sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。

sleep 不出让系统资源;wait是进入线程等待池等待,出让系统资源,其他线程可以占用CPU。一般wait不会加时间限制,因为如果wait线程的运行资源不 够,再出来也没用,要等待其他线程调用notify/notifyAll唤醒等待池中的所有线程,才会进入就绪队列等待OS分配系统资源。 sleep(milliseconds)可以用时间指定使它自动唤醒过来,如果时间不到只能调用interrupt()强行打断。

Thread.Sleep(0)的作用是“触发操作系统立刻重新进行一次CPU竞争”。


3、使用范围:wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用
   synchronized(x){
      x.notify()
     //或者wait()
   }


4、sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常


阅读(2433) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~