zoukankan      html  css  js  c++  java
  • UNP学习笔记之三POSIX Signal Handling

    说道多进程的svr网络模型,免不了会用到一些进程间通信的工具,在对简单的基于fork的并发服务器进行介绍以后,这里简单地介绍了一下信号处理:

    1. 1、信号也称为软件中断,信号的产生总是异步的,进程无法提前知道信号会什么时候发生。
    2. 2、信号可以在进程间发送,也可以是内核发送给进程。

    3、每一个信号产生时,都会触发一个相关的行为(函数)执行,这个行为(函数)我们可以使用sigaction函数定义.

    4、对于信号所关联的行为,我们有以下3种选择:

    当一个特定的信号发生时,可以执行一个自定义的函数,这个函数称之为“信号处理器”,这个函数执行的操作我们称之为捕获了一个信号。但是信号SIGKILL和SIGSTOP不能被捕获。大多数的程序可以使用sigaction来指定函数。少部分信号需要一些附加的操作才能捕获,例如:SIGIO,SIGPOLL,SIGURG。

    设置行为值为SIG_IGN时,在信号发生时将不做任何操作,但是信号SIGKILL和SIGSTOP不能被忽略。

    可以将行为默认设置为SIG_DFL。在信号发生时,默认的信号行为大多数是终止整个进程;还有一些进程会在进程的执行目录下面生成core文件;有少量信号的默认行为是被忽略掉的(SIGCHLD和SIGURG)。

    有信号处理的svr

    #include        "unp.h"

    int main(int argc, char **argv)
    {
            int                                     listenfd, connfd;
            pid_t                           childpid;
            socklen_t                       clilen;
            struct sockaddr_in      cliaddr, servaddr;
            void                            sig_chld(int);

            listenfd = Socket(AF_INET, SOCK_STREAM, 0);

            bzero(&servaddr, sizeof(servaddr));
            servaddr.sin_family      = AF_INET;
            servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
            servaddr.sin_port        = htons(SERV_PORT);

            Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));

            Listen(listenfd, LISTENQ);

            Signal(SIGCHLD, sig_chld); //进行信号注册处理,在子进程结束时候通知父进程。

            for ( ; ; ) {
                    clilen = sizeof(cliaddr);
                    connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);

                    if ( (childpid = Fork()) == 0) {        /* child process */
                            Close(listenfd);        /* close listening socket */
                            str_echo(connfd);       /* process the request */
                            exit(0);
                    }
                    Close(connfd);                  /* parent closes connected socket */
            }
    }

    #include        "unp.h"

    void sig_chld(int signo)
    {
            pid_t   pid;
            int             stat;

            pid = wait(&stat);//阻塞至子进程退出时候继续执行。
            printf("child %d terminated\n", pid);
            return;
    }

    信号注册行为的函数如下:

    /* include signal */
    #include        "unp.h"

    Sigfunc *signal(int signo, Sigfunc *func)
    {
            struct sigaction        act, oact;

            act.sa_handler = func;
            sigemptyset(&act.sa_mask);
            act.sa_flags = 0;
            if (signo == SIGALRM) {
    #ifdef  SA_INTERRUPT
                    act.sa_flags |= SA_INTERRUPT;   /* SunOS 4.x */
    #endif
            } else {
    #ifdef  SA_RESTART
                    act.sa_flags |= SA_RESTART;             /* SVR4, 44BSD */
    #endif
            }
            if (sigaction(signo, &act, &oact) < 0)
                    return(SIG_ERR);
            return(oact.sa_handler);
    }
    /* end signal */

  • 相关阅读:
    Win32汇编
    Boost ASIO 实现异步IO远控
    Python 使用oslo.vmware管理ESXI虚拟机
    Python 巡检接入钉钉机器人
    Django Ajax序列化与反序列化
    Nacos 认证绕过
    Lanproxy 遍历目录漏洞 CVE-2021-3019 附批量POC
    Apache Solr 全版本任意读取文件漏洞
    垂直水平居中的多种方法 主要的4种
    vue provide/inject 父组件如何给孙子组件传值
  • 原文地址:https://www.cnblogs.com/shanks/p/1505373.html
Copyright © 2011-2022 走看看