我们经常会遇到为阻塞操作设置超时的问题,比如说阻塞套接字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. 服务器环境配置安装(mysql+redis+nodejs+nginx)

    公司用来测试的服务器挂了,最后重装了系统,需要重新配置程序运行环境,linux上安装不是很熟悉,特此记录一下. 首先获取系统版本信息: 参考:获取Linux系统版本信息 一.mysql 1. 安装 安 ...

  2. 打包部署到tomcat

    部署到tomcat的方法 注意:在eclipse 或 idea 上需要引入外部tomcat 1.将程序打成war包启动tomcat 2.将target 文件下内容压缩城zip,发布到tomcat RO ...

  3. MYSQL 添加外键报错

    2014年6月16日 10:48:51 出错的部分提示摘录: #1452 - Cannot add or update a child row: a foreign key constraint fa ...

  4. 解决创建maven项目Could not resolve archetype org.apache.maven.archetypes:maven-archetype-quickstart问题

    今天用eclipse创建项目的时候报错如下图: 解决方案: 1.下载最新版maven-archetype-quickstart-1.1.jar   2.命令行到下载目录下执行mvn install:i ...

  5. maven dependencies 报错

    maven配置的环境变量有问题: 用最新的maven替换系统默认的setting.xml文件即可

  6. 绘图: matplotlib核心剖析

    参考:http://www.cnblogs.com/vamei/archive/2013/01/30/2879700.html http://blog.csdn.net/ywjun0919/artic ...

  7. 动态规划(dp)专题

    航线设置   问题描述在美丽的莱茵河畔,每边都分布着N个城市,两边的城市都是唯一对应的友好城市,现需要在友好城市间开通航线以加强往来,但因为莱茵河常年大雾,如果开设的航线发生交叉就有可能出现碰船的现象 ...

  8. WebApi帮助类

    public class HttpClientBase { /// <summary> /// HttpClient实现Post请求 /// </summary> protec ...

  9. SqlServer 批量备份

    -- 实现方式1:使用游标 DECLARE @FileName VARCHAR(200), @CurrentTime VARCHAR(50), @DBName VARCHAR(100), @SQL V ...

  10. docker:定制node.js的版本

    本想用alpine,但如果想使用node.js 6.3.1版本的软件, 总会搞不定glibc和libstdc++报一个无法识别版本信息的错误. 搞了一天,算了.使用debian:stretch-sli ...