【TCP/IP】多进程服务器的实现(进阶) - 信号处理及signal、sigaction函数

这篇具有很好参考价值的文章主要介绍了【TCP/IP】多进程服务器的实现(进阶) - 信号处理及signal、sigaction函数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

信号

signal函数

sigaction函数

用信号来处理僵尸进程


        在之前我们学习了如何处理“僵尸进程”,不过可能也会有疑问:调用wait和waitpid函数时我们关注的始终是在子进程上,那么在父进程上如何实现对子进程的管控呢?为此,我们引入一个概念——信号处理。

信号

        信号这个概念大家应该不陌生,诸如汽车的鸣笛、闹钟的响铃等,这些都是信号,用以告诉人们某件事情的发生。而在计算机中,同样有这个概念。在编程上常用信号来对接收到的某些数据或者指令做出与之对应的响应处理。

signal函数

        让我们先来看看<signal.h>库中的signal函数,其结构如下:

#include <signal.h>

void (*signal (int signo , void (*func)(int))) (int);


// 为了在产生信号时调用,返回之前注册的函数指针。

// 函数名:signal
// 参数 int signo, void (* func)(int)
// 返回类型:参数为int型,返回void型函数指针。

        signo参数用来标记触发的条件,func则为将要调用的函数的指针

        与参数所相关的宏有:

  • SIGALRM: 按照已通过调用alarm函数注册的时间为信号点。
  • SIGINT: 输入CTRL+C暂停时为信号点
  • SIGCHILD: 子进程终止时为信号点。

补充:

        alarm函数的用法及意义如下:

#include <unistd.h>

unsigned int alarm (unsigned int seconds);

// 返回 以秒为单位 的,距 SIGALRM 信号发生时所剩余的时间

        其中 seconds 参数用以传入欲设定的alarm的周期(以s为单位)。若传递0至变量中,则意味着将会取消对SIGALRM信号的预约。同时,若未指定该产生信号所对应的处理函数时,则该进程将被终止。

        接下来,让我们来验证下 SIGALRMSIGINT 两种触发条件下的signal函数吧。

singal.cpp

#include <stdio.h>
#include <unistd.h>
#include <signal.h>

void alarmEvent(int sig) //包括下面的keyEvent,这类函数被称为信号处理器(Handler)
{
    if (sig == SIGALRM)
    {
        printf("Time out!\n");
    }

    alarm(2);
}

void keyEvent(int sig)
{
    if (sig == SIGINT)
    {
        printf("\nCTRL+C pressed\n");
    }
}

int main(int argc, char *argv[])
{
    //注册:设置SIGGALRM为触发条件,调用alarmEvent函数
    signal(SIGALRM, alarmEvent); 
    //注册:设置SIGINT为触发条件,调用keyEvent函数
    signal(SIGINT, keyEvent);

    //设置时钟周期为2s
    alarm(2); 

    for (size_t i = 0; i < 5; i++)
    {
        printf("Wait for an event to occur...\n");
        sleep(50);  //实际操作上无法休眠50s
    }

    return 0;
}

        运行结果:

【TCP/IP】多进程服务器的实现(进阶) - 信号处理及signal、sigaction函数

        想法得到验证。

        Q:为什么程序在实际运行上,没有感受到在等待事件发生后的50s延迟呢?

        A:信号在响应时,尽管存在有阻塞态的进程,但操作系统为了调用信号处理器,会强制唤醒进行阻塞态(sleep中的)进程,并且该进程一旦被唤醒,将不会在进入睡眠状态,因此在操作上,我们并不会感受到会有长达50s的延迟。

sigaction函数

        sigaction是对signal函数的升级,能够更好地支持不同的操作系统(signal函数在不同的操作系统中用法和效果可能会不同)。

        让我们来看下这个函数长什么样:

#include <signal.h>

int sigaction(int signo , const struct sigaction * act , struct sigaction *
oldact) ;

// 成功时退回0,失败时退回-1。

/* 参数含义 */

// signo:与signal函数相同,传递信号信息
// act:对应第一个参数的信号处理函数
// oldact:通过此参数获取之前注册的信号处理函数指针,不需要时则传递0。

        对于sigaction,它的结构体定义如下:

 //结构体做了简化,实际上其中一些变量用宏和typedef做了进一步封装

 struct sigaction
    {
        void (*sa_handler)(int);
        sigset_t sa_mask;
        int sa_flags;
        void (*sa_restorer)(void);
    };

        参数意义参考以下: 

  • sa_handler:用以保存信号处理函数的指针值
  • sa_mask:需要滤除的附加信号集,省略
  • sa_flags:特殊标记符,省略
  • sa_restorer:欲重置的(信号)处理器,省略

        OK,让我们编写一个实例来验证这个函数的功能

sigaction.cpp

#include <stdio.h>
#include <unistd.h>
#include <signal.h>

void alarmEvent(int sig)
{
    if (sig == SIGALRM)
    {
        printf("Time out!\n");
    }
    alarm(2);
}

int main(int argc, char *argv[])
{
    //声明sigaction结构体变量act
    struct sigaction act;
    //将信号处理函数存入结构体中
    act.sa_handler = alarmEvent;
    //将sa_mask成员的所有位初始化为0
    sigemptyset(&act.sa_mask);
    //将sa_flags成员同样初始化为0
    act.sa_flags = 0;
    //注册:触发条件为SIGALARM,调用act信号处理器中的信息
    sigaction(SIGALRM, &act, 0);

    alarm(2);

    for (size_t i = 0; i < 5; i++)
    {
        printf("Wait for an event to occur...\n");
        sleep(50);
    }

    return 0;
}

        运行结果:

【TCP/IP】多进程服务器的实现(进阶) - 信号处理及signal、sigaction函数

        结果验证了之前的想法。

用信号来处理僵尸进程

        当我们掌握signal、sigaction两个函数后,便可更好地去管控父、子进程了。在之前我们采用的是wait、waitpid函数来销毁僵尸进程。接下来,请大家尝试一下用信号来消灭“僵尸进程”吧!

        欢迎大家在评论区贴出你们的代码~文章来源地址https://www.toymoban.com/news/detail-478783.html

到了这里,关于【TCP/IP】多进程服务器的实现(进阶) - 信号处理及signal、sigaction函数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • TCP服务器实现—多进程版,多线程版,线程池版

    目录 前言 1.存在的问题 2.多进程版 3.多线程版 4.线程池版 总结         在上一篇文章中使用TCP协议实现了一个简单的服务器,可以用来服务端和客户端通信,但是之前的服务器存在一个问题,就是当有多个客户端连接服务器的时候,服务器只能和一个客户端通信,其它的客

    2024年02月12日
    浏览(31)
  • [Linux] 网络编程 - 初见TCP套接字编程: 实现简单的单进程、多进程、多线程、线程池tcp服务器

    网络的上一篇文章, 我们介绍了网络变成的一些重要的概念, 以及 UDP套接字的编程演示. 还实现了一个简单更简陋的UDP公共聊天室. [Linux] 网络编程 - 初见UDP套接字编程: 网络编程部分相关概念、TCP、UDP协议基本特点、网络字节序、socket接口使用、简单的UDP网络及聊天室实现…

    2024年02月16日
    浏览(45)
  • 多进程并发TCP服务器模型(含客户端)(网络编程 C语言实现)

    摘要 :大家都知道不同pc间的通信需要用到套接字sockte来实现,但是服务器一次只能收到一个客户端发来的消息,所以为了能让服务器可以接收多个客户端的连接与消息的传递,我们就引入了多进程并发这样一个概念。听名字就可以知道--需要用到进程,当然也有多线程并发

    2024年02月17日
    浏览(38)
  • 网络通信(13)-C#TCP服务器和客户端同时在一个进程实现的实例

    有时项目需求中需要服务器和客户端同时在一个进程实现,一边需要现场接收多个客户端的数据,一边需要将数据汇总后发送给远程服务器。下面通过实例演示此项需求。 C#TCP服务器和客户端同时在一个进程实现的实例如下: 界面设计 UI文件代码

    2024年01月22日
    浏览(47)
  • Socket网络编程(TCP/IP)实现服务器/客户端通信。

    一.前言 回顾之前进程间通信(无名管道,有名管道,消息队列,共享内存,信号,信号量),都是在同一主机由内核来完成的通信。 那不同主机间该怎么通信呢? 可以使用Socket编程来实现。 Socket编程可以通过网络来实现实现不同主机之间的通讯。 二.Socket编程的网络模型如

    2024年02月08日
    浏览(64)
  • Linux网络编程二(TCP三次握手、四次挥手、TCP滑动窗口、MSS、TCP状态转换、多进程/多线程服务器实现)

    TCP三次握手 TCP 三次握手 (TCP three-way handshake)是TCP协议建立可靠连接的过程,确保客户端和服务器之间可以进行可靠的通信。下面是TCP三次握手的详细过程: 假设客户端为A,服务器为B 1 、第一次握手(SYN=1,seq=500) A向B发送一个带有SYN标志位的数据包,表示A请求建立连接。

    2024年02月06日
    浏览(44)
  • 【TCP/IP】利用I/O复用技术实现并发服务器 - select函数

    目录 I/O复用技术 select函数 设置文件描述符 指定监视范围 设置超时 I/O复用服务器端的实现        由服务器创建多个进程来实现并发的做法有时会带来一些问题,比如:内存上的开销、CPU的大量占用等,这些因素会消耗掉服务器端有限的计算资源、进而影响程序之间的执

    2024年02月08日
    浏览(34)
  • Linux网络编程二(TCP图解三次握手及四次挥手、TCP滑动窗口、MSS、TCP状态转换、多进程/多线程服务器实现)

    1、TCP三次握手 TCP 三次握手 (TCP three-way handshake)是 TCP协议建立可靠连接 的过程,确保客户端和服务器之间可以进行可靠的通信。下面是TCP三次握手的 详细过程 : 假设客户端为A,服务器为B。 (1) 第一次握手 第一次握手(SYN=1,seq=500) A向B发送一个带有 SYN 标志位的数据包,

    2024年04月22日
    浏览(35)
  • Linux网络编程之TCP/IP实现高并发网络服务器设计指南

    目录 引言: 多进程服务器 例程分享: 多线程服务器  例程分享: I/O多路复用服务器 select 例程分享: poll 例程分享: epoll 例程分享: 总结建议         随着互联网的迅猛发展,服务器面临着越来越多的并发请求。如何设计一个能够高效处理大量并发请求的服务器成为

    2024年02月20日
    浏览(39)
  • 网络编程(一)TCP单进程服务器编程详解

    想要学习socket网络编程的读者一定要首先学好计算机网络的理论知识,包括 1)osi网络七层模型与ip四层模型 2)套接字含义 3)局域网通信过程 4)广域网通信过程 5)tcp,udp通信协议,在这两个协议中的连接建立,数据封装,传输过程,传输中可能遇到的问题的处理(差错控

    2024年02月15日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包