我们经常会遇到为阻塞操作设置超时的问题,比如说阻塞套接字read读取设置10秒超时,其中一个办法就是调用alarm函数,它在指定超时时期产生SIGALRM信号,使得阻塞操作中断。

但其弊端在于:

1、可能干扰进程中现有的alarm调用,如timer、settimer、sleep等。

2、在多线程化程序中正确使用信号却非常困难;所以建议只是在未线程化或单线程化的程序中使用本技术。

#include <stdio.h>
#include <netinet/in.h>//for struct sockaddr_in
#include <string.h>//for memset
#include <signal.h>//for signal typedef void (*sighandler_t)(int); static void
read_alarm(int signo)
{
return;
} int main()
{
int conn_sock;
struct sockaddr_in ser_addr;
int ret;
char buf[];
sighandler_t src_sig;
struct sigaction sa_alarm; conn_sock = socket(AF_INET, SOCK_STREAM, );
if (conn_sock < )
{
perror("socket error");
return -;
} memset(&ser_addr, , sizeof(ser_addr));
ser_addr.sin_family = AF_INET;
ser_addr.sin_port = htons();
inet_pton(AF_INET, "127.0.0.1", &ser_addr.sin_addr); ret = connect(conn_sock, (struct sockaddr *)&ser_addr, sizeof(ser_addr));
if (ret < )
{
perror("connect error");
return -;
} //src_sig = signal(SIGALRM, read_alarm);
sa_alarm.sa_flags = SA_RESETHAND;
sa_alarm.sa_handler = read_alarm;
sigaction(SIGALRM, &sa_alarm, NULL);
alarm();
ret = read(conn_sock, buf, sizeof(buf));
if (ret < )
{
perror("read error");
}
else if (ret == )
{
printf("close by peer\n");
}
else
{
printf("recv %d bytes\n", ret);
}
alarm();
//signal(SIGALRM, src_sig);
return ;
}

运行结果:

read error: Interrupted system call

在linux系统中使用signal函数,read超时10秒后不会被中断,因为中断后会自动重启被中断的read。

需要采用segaction函数来验证,当read超过10秒时,alarm发出SIGALRM信号,read被中断。

使用SIGALRM信号为阻塞操作设置超时的更多相关文章

  1. 服务器编程入门(13) Linux套接字设置超时的三种方法

    摘要:     本文介绍在套接字的I/O操作上设置超时的三种方法. 图片可能有点宽,看不到的童鞋可以点击图片查看完整图片.. 1 调用alarm 使用SIGALRM为connect设置超时 设置方法: ...

  2. SIGALRM信号和SIGCHID信号

    在进行堵塞式系统调用时.为避免进程陷入无限期的等待,能够为这些堵塞式系统调用设置定时器.Linux提供了alarm系统调用和SIGALRM信号实现这个功能. 要使用定时器.首先要安装SIGALRM信号 ...

  3. linux中的两个很重要的信号:SIGALRM信号和SIGCHID信号

    在进行堵塞式系统调用时.为避免进程陷入无限期的等待,能够为这些堵塞式系统调用设置定时器.Linux提供了alarm系统调用和SIGALRM信号实现这个功能.         要使用定时器.首先要安装S ...

  4. Unix网络编程 高级IO套接字设置超时

    我们知道.对于一个套接字的读写(read/write)操作默认是堵塞的.假设当前套接字还不可读/写,那么这个操作会一直堵塞下去,这样对于一个须要高性能的server来说,是不能接受的.所以,我们能够在 ...

  5. Linux系统编程(23)——信号的阻塞

    实际执行信号的处理动作称为信号递达(Delivery),信号从产生到递达之间的状态,称为信号未决(Pending).进程可以选择阻塞(Block)某个信号.被阻塞的信号产生时将保持在未决状态,直到进程 ...

  6. 2.3 linux中的信号分析 阻塞、未达

    信号的阻塞.未达: linux中进程1向进程2发送信号,要经过内核,内核会维护一个进程对某个信号的状态,如下图所示: 当进程1向进程2发送信号时,信号的传递过程在内核中是有状态的,内核首先要检查这个信 ...

  7. python调用函数设置超时机制

    有时候需要给函数设置超时机制,以防止它卡住我们的程序,这里可以用python的signal模块,signal模块可以实现程序内部的信号处理. # coding:utf8 import time imp ...

  8. FFmpeg命令读取RTMP流如何设置超时时间

    子标题:FFmpeg命令录制RTMP流为FLV文件时如何设置超时时间 | FFmpeg命令如何解决录制产生阻塞的问题0x001: 前言 今天在测试程序时遇到两个问题.Q1:ffmpeg录制RTMP流并 ...

  9. accpet和connect设置超时

    三次握手 TCP连接建立的开始是三次握手,通过三次交互确认连接成功,在客户端调用connect时,客户端发送sync消息给服务端,服务端收到sync消息后,返回一个ack+sync,并等待ack,客户 ...

随机推荐

  1. 运算符,比如+, -, >, <, 以及下标引用[start:end]等等,从根本上都是定义在类内部的方法。

    python解释器在碰到+号运算符时,会调用加号前面的对象的__add__方法 class a: def __add__(self,b): print "ghh" aa=a() a ...

  2. J - FatMouse's Speed dp

    题目链接: https://vjudge.net/contest/68966#problem/J 找最长子串并且记录路径. TLE代码: #include<iostream> #inclu ...

  3. 不使用第三方软件、使用IE11自带功能来屏蔽浏览器广告

    第一步: 下载后面的附件http://files.cnblogs.com/limits/IE11%E5%8E%BB%E5%B9%BF%E5%91%8A.zip 打开此路径IE11跟踪保护+CSS去广告 ...

  4. 洛谷P3379倍增LCA

    传送门 #include <iostream> #include <cstdio> #include <cstring> #include <cmath> ...

  5. 解决MySQL忘记root密码

    网上有很多关于忘记MySQL root密码的一些文章,里面都有写怎么去解决,但有时觉得写得太恶心,要么一字不漏的抄别人的,要么就说得不清不楚,好了,不吐槽了,以下是解决的整个过程. 首先我们要知道忘记 ...

  6. 使用before_request来做权限和用户检查

    因为使用restful方式,因此每次用户访问都会上传带入auth_key,如jwt等,因此可在@app.before_request中做权限的检查. @app.app.before_request d ...

  7. Simple Web API Server in Golang (2)

    In this challenge, I tried to implement a simple OAuth2 server basing on Simple Web API Server in [1 ...

  8. #JS 窗口resize避免触发多次

    window窗口改变时触发resize,如何避免多次执行,设置一个300ms定时器即可. //窗口变化监听,避免resize多次执行卡顿 var resizeTimer = null; $(windo ...

  9. Git(四)Git的分支管理

    一. 创建合并分支原理 在我们每次的提交,Git都把它们串成一条时间线,这条时间线就是一个分支.截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支.HEAD指针严格来说不是指 ...

  10. PowerDesigner的安装

    1.下载 2.步骤 3.效果 二:破解 1.参考文档 https://www.7down.com/soft/180716.html 2.说明 主要是一个文件,替换掉文件中的文件即可.