zoukankan      html  css  js  c++  java
  • 第十二篇:并发回射服务器的具体实现及其中僵尸子进程的清理( 上 )

    前言

           本文将分为两个部分,第一部分具体实现一对并发回射服务器/客户程序( 看过前面那篇文章的这部分可不看 重复了 );第二部分为服务器添加僵尸子进程自动清理机制。

           那么服务器具体怎么实现并发?怎么会有僵尸进程?僵尸进程又是什么?如何处理这些僵尸进程 ... 本文将为你一一解惑。

    回射并发服务器

           功能:接收用户发送过来的数据后再发送回用户,且能同时处理多个用户请求。

           大体思路:每当收到用户请求,服务器就fork一个子进程,让子进程去处理客户请求。

           实现代码

     1 #include    "unp.h"
     2 
     3 int
     4 main(int argc, char **argv)
     5 {
     6     int                    listenfd, connfd;
     7     pid_t                childpid;
     8     socklen_t            clilen;
     9     struct sockaddr_in    cliaddr, servaddr;
    10 
    11     listenfd = Socket(AF_INET, SOCK_STREAM, 0);
    12 
    13     bzero(&servaddr, sizeof(servaddr));
    14     servaddr.sin_family      = AF_INET;
    15     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    16     servaddr.sin_port        = htons(SERV_PORT);
    17 
    18     Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
    19 
    20     Listen(listenfd, LISTENQ);
    21 
    22     for ( ; ; ) {
    23         clilen = sizeof(cliaddr);
    24         connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);
    25 
    26         /*
    27          * 子进程代码
    28         */
    29         if ( (childpid = Fork()) == 0) {
    30             // 子进程启动后首先关闭监听套接字
    31             Close(listenfd);    
    32             // 回射处理
    33             str_echo(connfd);
    34             // 退出子进程
    35             exit(0);
    36         }
    37         // 关闭连接套接字
    38         Close(connfd);            
    39     }
    40 }
     1 #include    "unp.h"
     2 
     3 void
     4 str_echo(int sockfd)
     5 {
     6     ssize_t        n;
     7     char        buf[MAXLINE];
     8 
     9 again:
    10     while ( (n = read(sockfd, buf, MAXLINE)) > 0)
    11         Writen(sockfd, buf, n);
    12 
    13     if (n < 0 && errno == EINTR)
    14         goto again;
    15     else if (n < 0)
    16         err_sys("str_echo: read error");
    17 }

    回射并发客户端

           功能:向服务器发送数据,接收服务器反射回的信息并打印。

           大体思路:略。

           实现代码

     1 #include    "unp.h"
     2 
     3 int
     4 main(int argc, char **argv)
     5 {
     6     int                    sockfd;
     7     struct sockaddr_in    servaddr;
     8 
     9     if (argc != 2)
    10         err_quit("usage: tcpcli <IPaddress>");
    11 
    12     sockfd = Socket(AF_INET, SOCK_STREAM, 0);
    13 
    14     bzero(&servaddr, sizeof(servaddr));
    15     servaddr.sin_family = AF_INET;
    16     servaddr.sin_port = htons(SERV_PORT);
    17     Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
    18 
    19     Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
    20 
    21     str_cli(stdin, sockfd); // 与服务器通信    
    22 
    23     exit(0);
    24 }
     1 #include    "unp.h"
     2 
     3 void
     4 str_echo(int sockfd)
     5 {
     6     ssize_t        n;
     7     char        buf[MAXLINE];
     8 
     9 again:
    10     while ( (n = read(sockfd, buf, MAXLINE)) > 0)
    11         Writen(sockfd, buf, n);
    12 
    13     if (n < 0 && errno == EINTR)
    14         goto again;
    15     else if (n < 0)
    16         err_sys("str_echo: read error");
    17 }

    运行测试

    1. 在一个终端以超级用户权限启动服务器

    2. 在另几个终端打开客户端并输入IP地址参数127.0.0.1

    3. 执行回射测试,运行情况如下( 几个客户终端都运行正常 ):

            

    问题发现

           看似这个并发回射程序已经做好了。但,很遗憾,不是的。我们接下来的观察将会带我们进入本文真正的主题:僵尸子进程

           首先退出这几个客户终端。按照我们最初的设想,这几个子进程应该已经结束了。但事实真是这样吗?我们在终端执行以下命令进行查看:

           

           图中,STAT显示表示进程状态,Z+表示进程正处在“ 僵尸 ”状态。通过比对其PID与PPID不难发现,服务器中处理客户端的进程并没有“ 死去 ”,而是变成了“ 僵尸 ”

    什么是僵尸进程

           僵尸进程就是已经撤销但依然占着资源的进程。

    为什么要有僵尸进程

           设置僵死状态的目的是为了维护子进程的信息。父进程有时需要获取到一些已经撤销的子进程的信息。

    如何处理僵尸进程

           对于本例中的僵尸进程,我们当然要将其清理掉并释放其占用的资源。

  • 相关阅读:
    《CLR via C#》笔记——运行时序列化(2)
    《CLR via C#》笔记——程序集的加载和反射(2)
    《CLR via C#》笔记——线程基础
    《CLR via C#》笔记——AppDomain(1)
    《CLR via C#》笔记——运行时序列化(1)
    《CLR via C#》笔记——程序集的加载和反射(3)
    《CLR via C#》笔记——AppDomain(2)
    C# 3.0 新特性概览
    【JAVASCRIPT】jquery实现新闻滚动效果
    【JAVASCRIPT】jquery实现图片笼罩效果
  • 原文地址:https://www.cnblogs.com/muchen/p/6357432.html
Copyright © 2011-2022 走看看