进程

1、创建进程  fork()

使用fork()函数来创建进程,fork后,生成子进程,但二者执行顺序不固定。    详解见  http://blog.csdn.net/tong_xin2010/article/details/38469471

调用fork()的程序需要包含头文件<sys/types.h>和<unistd.h>.

fork()返回“子进程的进程号”,因为子进程没有子进程,所以子进程的fork返回0,父进程的fork返回子进程的进程号。

 

2、获取进程号  getpid()、getppid()

需要包含头文件<unistd.h>

pid_t  pid,ppid;  

进程标识pid,是一个16比特的整数.

pid=getpid();    //获取自身进程号

ppid=getppid();    //获取父进程的进程号

            //在Linux中,除了init进程外,每个进程都有其父进程。

 

3、终止进程

子进程创建后独立于父进程运行,执行先后顺序依据具体计算机的调度算法,没有统一答案

每个进程退出时都会有一个退出码,返回给其父进程。退出码由终止进程作为参数传递给exit函数,或者作为main()函数的return()所返回的值。

①通过向进程发送相关信号来终止进程:如Linux下通过kill命令向进程发送一个SIGKILL信号(-9),即可终止进程。  kill -s SIGKILL 2839   (通过信号终止进程2839)

②若程序未设置对某些信号的相关处理程序,当进程收到这些未设置的信号时,默认的处理通常就是终止进程。(比如一个网络应用进程由于I/O阻塞,此时若收到意外的信号,则通常会终止应用的运行)

③调用exit()。

④main函数执行return语句退出进程。

 

4、相关函数

  4.1 wait()和waitpid() 

  当进程调用wait()后,自身被阻塞,自动检测是否有子进程退出处于僵死状态:一旦检测到,wait就会收集子进程的信息并释放子进程占据的各种资源,然后返回并解除阻塞状态;若无子进程结束或处于僵死状态,则wait就会一直阻塞在这里。因此可以使用wait()来解决进程同步的问题,比如子进程创建文件,父进程向该文件中写入数据,有确切的执行顺序要求,这个时候就可以让父进程调用wait()来等待子进程执行完毕(即父进程的执行需要以子进程的成功执行为基础,即需要用到子进程的执行结果)。

  waitpid()的功能和wait()类似,但更加灵活(因为多了两个用户控制的参数:pid和options),可以将wait()理解为waitpid()的特例。

pid用以指定waitpid()检测的子进程;options提供额外的参数来控制waitpid(),其可取值有0、WNOHANGWUNTRACED。设为WONHANG时,即使没有等到子进程退出,也会立即退出,不会一直等待下去。

详细介绍参见  http://blog.163.com/lqy_super/blog/static/1997510212012112953858902/

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
main(){
int status;
pid_t pc,pr;
pc=fork();
if(pc<0) 
    printf("error ocurred!/n");
else if(pc==0){ 
    printf("This is child process with pid of %d./n",getpid());
    exit(3); 
        }
else{ 
    pr=wait(&status);
    if(WIFEXITED(status)){   //宏WIFEXITED(status)用来指示子进程是否正常退出,正常退出时返回一个非零值。
        printf("the child process %d exit normally./n",pr);
        printf("the return code is %d./n",WEXITSTATUS(status));
        }
  else 
      printf("the child process %d exit abnormally./n",pr);
}

 

  4.2 sleep()

“占着内存睡觉”,单位为毫秒。

 详情参见  http://www.cnblogs.com/plmnko/archive/2010/10/15/1851854.html  

      https://zhidao.baidu.com/question/75503928.html  

      http://www.linuxidc.com/Linux/2013-03/81455.htm  

      http://baike.baidu.com/link?url=qgfmahmbIvF2TwrpKGG9AnxiQHOWH5d3SmSkMuvbnt_XXlHLBM4FPqa_gvoQ6J_jSqXyZ3uSDdHC_6OKHdteba

 

5、僵死进程/僵尸进程        进程状态为 Z

由于子进程的运行独立于父进程,所以当子进程先于父进程执行完毕时,代表子进程的数据结构并不会立即从进程表中销毁(尽管子进程不会再执行)。这种不再活动的进程即为僵死进程

之所以子进程不会自动销毁自己并释放所占据的系统资源,是因为他要把他的退出代码保存起来供之后父进程调用wait后使用,所以可以通过父进程调用wait()来获取子进程的终止信息,然后释放相关资源。

int main(){
  pid_t pid;
  pid=fork();
  if(pid>0){
    sleep(60);  //父进程休眠60s,在此期间,子进程执行完毕退出,得不到父进程的善后处理,此时的子进程即为“僵死进程“。
  }
  else{
    exit(0);    //子进程立即退出
  }
}

 

6、Linux下相关命令

①查看当前运行进程  ps

ps -A      显示所有进程信息

ps -ef     显示所有进程信息(更详细,包括pid、ppid、command)

ps -u root   显示用户root的进程

ps -ef|grep ssh     与grep搭配查找特点进程

ps aux     列出所有当前正在内存中的进程

ps aux | egrep '(cron|syslog)'  找出与 cron 与 syslog 这两个服务有关的进程

ps -aux > ps001.txt    把所有进程显示出来,并输出到ps001.txt

命令详情参见  http://www.cnblogs.com/peida/archive/2012/12/19/2824418.html

 

②定点终止进程    kill  Ctrl+C

前台正在运行进程的终止使用Ctrl+C,后台进程的终止则使用kill命令。

kill -l   列出所有信号名称

kill 3265    杀死ID为3265的进程

kill -9 3268    -9代表信号强制终止,该命令彻底杀死3268进程

kill -u zt    杀死用户zt的所有进程,也可使用与ps的组合命令  kill -9 $(ps -ef | grep zt)

        init进程的ID为1,始终是第一个进程,不可杀,也杀不死。

命令详情参见  http://www.cnblogs.com/peida/archive/2012/12/20/2825837.html

posted @ 2016-11-10 21:02  zhengmengen  阅读(142)  评论(0)    收藏  举报