zoukankan      html  css  js  c++  java
  • 服务器的基本问题避免

    TCP/IP协议的 11 中状态;

    开发服务器中避免出现的问题:

    一。服务器中表面出现僵尸进程:(SIGCHLD信号的处理)

    1. 多进程服务器; 一个管理进程, 当客户端链接时, 起一个子进程与客户端进程通信;

    2. 客户端:普通客户端程序, 与服务器之间保持长链接。

    3.问题:

      此时设计到一个问题,当起 n 个客户端连接服务器时;服务器会产生 n 个子线程,用于各客户端通信,此时,加入一个客户端主动关闭链接,

      服务器应该关掉它对应的子进程,并对这个子进程进行回收,防止产生僵尸进程。

      ① 注册信号,当客户端主动断开连接, 服务器子进程会退出, 此时会向父进程,发送 SIGCHID  信号;父进程注册信号处理函数; signal(SIGCHID, func_data);

      func_data()   {   wait(NULL); }    (伪代码, 该函数的格式不对)。

      会调用该信号函数回收子进程;

      ②加入:多个链接客户端同时关闭连接, 此时会同时向服务器发送:FIN标识位,服务器多个子进程同时退出, 并同时向主进程 发出SIGCHID信号; 这时,上面的

      程序设计就出现问题。 因为: SIGCHID 信号是不可靠信号,当多个信号同时向父进程发送时, 服务器主进程可能回处理 1 个, 或多个 < n, 或者n个(理想状态),那么就会有很大可能产生僵尸进程。  为了避免这种情况的发生; 上面的信号注册函数, 就应该写成这样, 才可以避免该问题。

      func_data()   { int mypid = 0;  while( ( mypid = waitpid(-1, NULL, WNOHANG ) ) > 0 { ; (此处循环可以为空)} } 。

     二。通信中出现SIGPIPE信号:(SIGPIPE信号的处理和该信号出现的时机)

      1. 在网路通信中, 因为套接字为 全双工通信;

       当 server 关闭 一个套接字后,client 继续向该套接字发送消息, 按照 TCP 协议规定, client 会收到一个RST响应, client再用该套接字向 server发送数据时,

      会收到SIGPIPE信号, 该信号的默认处理方式:终端当前进程;如果不对该信号进行处理,会造成当前的程序不稳定, 出现上述情况时,会使client 退出。

      (server端亦然);

      2.  为避免程序退出, 就需要对该信号进行处理, 两种方式: 1. 忽略该信号 signal(SIGPIPE, SIG_IGN); 2.捕捉该信号signal(SIGPIPE, 捕捉函数);

      3.对于产生信号,我们可以在产生信号前利用方法 signal(int signum, sighandler_t handler) 设置信号的处理。如果没有调用此方法,系统就会调用

      默认处理方法:中止程序,显示提示信息(就是我们经常遇到的问题)。我们可以调用系统的处理方法,也可以自定义处理方法。 

      系统里边定义了三种处理方法: 
      (1)SIG_DFL信号专用的默认动作:
        (a)如果默认动作是暂停线程,则该线程的执行被暂时挂起。当线程暂停期间,发送给线程的任何附加信号都不交付,直到该线程开始执行,但是SIGKILL除外。
        (b)把挂起信号的信号动作设置成SIG_DFL,且其默认动作是忽略信号 (SIGCHLD)。
      (2)SIG_IGN忽略信号
        (a)该信号的交付对线程没有影响
        (b)系统不允许把SIGKILL或SIGTOP信号的动作设置为SIG_DFL
      (3)SIG_ERR   

      项目中我调用了signal(SIGPIPESIG_IGN), 这样产生  SIGPIPE 信号时就不会中止程序,直接把这个信号忽略掉。

    三。close与shutdown的区别:(调用方式产生的不同效果,以及他们俩的实现基本原理)

      close() 与shutdown() 关闭套接字的区别:

      1.close(): 采用 引用计数技术;只有当关闭的套接字: 基数为0时, TCP协议 才会向对端发送 FIN 标识符, 表示该套接字关闭;

      2.shutdown(): 只要调该函数关闭套接字: 就会向对端发送 FIN 标识符, 表示 该套接字关闭;

        1.该函数的3种关闭方式: 

              1.SHUT_RD:值为0,关闭连接的读这一半。

              2.SHUT_WR:值为1,关闭连接的写这一半。

              3.SHUT_RDWR:值为2,连接的读和写都关闭。

      3.close与shutdown的区别主要表现在:

             close函数会关闭套接字ID,如果有其他的进程共享着这个套接字,那么它仍然是打开的,这个连接仍然可以用来读和写,并且有时候这是非常重要的 ,

      特别是对于多进程并发服务器来说。

             而shutdown会切断进程共享的套接字的所有连接,不管这个套接字的引用计数是否为零,那些试图读得进程将会接收到EOF标识,那些试图写的进程

      将会检测到SIGPIPE信号,同时可利用shutdown的第二个参数选择断连的方式。

    四。长链接、短链接

      1.长链接: 表示一直链接, 不断开;

        while(1){

          write();

          read();

        }close();

      2.短链接:发送完数据后,就断开。

         {    //该数据一轮 收发完后, 立即断开。

          write();

          read();

          close();   

        }

  • 相关阅读:
    SQL Server 中的事务与事务隔离级别以及如何理解脏读, 未提交读,不可重复读和幻读产生的过程和原因
    微软BI 之SSIS 系列
    微软BI 之SSIS 系列
    微软BI 之SSIS 系列
    微软BI 之SSIS 系列
    微软BI 之SSIS 系列
    微软BI 之SSAS 系列
    微软BI 之SSRS 系列
    微软BI 之SSRS 系列
    配置 SQL Server Email 发送以及 Job 的 Notification通知功能
  • 原文地址:https://www.cnblogs.com/yyx1-1/p/6241863.html
Copyright © 2011-2022 走看看