使用SIGALRM信号为阻塞操作设置超时
2017-10-23 00:51
453 查看
我们经常会遇到为阻塞操作设置超时的问题,比如说阻塞套接字read读取设置10秒超时,其中一个办法就是调用alarm函数,它在指定超时时期产生SIGALRM信号,使得阻塞操作中断。
但其弊端在于:
1、可能干扰进程中现有的alarm调用,如timer、settimer、sleep等。
2、在多线程化程序中正确使用信号却非常困难;所以建议只是在未线程化或单线程化的程序中使用本技术。
运行结果:
read error: Interrupted system call
在linux系统中使用signal函数,read超时10秒后不会被中断,因为中断后会自动重启被中断的read。
需要采用segaction函数来验证,当read超过10秒时,alarm发出SIGALRM信号,read被中断。
但其弊端在于:
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[1024]; sighandler_t src_sig; struct sigaction sa_alarm; conn_sock = socket(AF_INET, SOCK_STREAM, 0); if (conn_sock < 0) { perror("socket error"); return -1; } memset(&ser_addr, 0, sizeof(ser_addr)); ser_addr.sin_family = AF_INET; ser_addr.sin_port = htons(135); 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 < 0) { perror("connect error"); return -1; } //src_sig = signal(SIGALRM, read_alarm); sa_alarm.sa_flags = SA_RESETHAND; sa_alarm.sa_handler = read_alarm; sigaction(SIGALRM, &sa_alarm, NULL); alarm(10); ret = read(conn_sock, buf, sizeof(buf)); if (ret < 0) { perror("read error"); } else if (ret == 0) { printf("close by peer\n"); } else { printf("recv %d bytes\n", ret); } alarm(0); //signal(SIGALRM, src_sig); return 0; }
运行结果:
read error: Interrupted system call
在linux系统中使用signal函数,read超时10秒后不会被中断,因为中断后会自动重启被中断的read。
需要采用segaction函数来验证,当read超过10秒时,alarm发出SIGALRM信号,read被中断。
相关文章推荐
- 使用SIGALRM信号为阻塞操作设置超时
- CSocket同步操作阻塞时设置超时的解决方案 推荐
- libcurl使用easy模式阻塞卡死等问题的完美解决---超时设置
- libcurl使用easy模式阻塞卡死等问题的完美解决---超时设置
- Linux定时器处理之实时信号使用,消息队列阻塞模型,避免超时等待
- 《Ext JS高级程序设计》节选:在CRUD操作中restful的设置以及使用Ext.Direct的问题
- 《Ext JS高级程序设计》节选:在CRUD操作中restful的设置以及使用Ext.Direct的问题
- 《Ext JS高级程序设计》节选:在CRUD操作中restful的设置以及使用Ext.Direct的问题
- 《Ext JS高级程序设计》节选:在CRUD操作中restful的设置以及使用Ext.Direct的问题
- IIS 6.0中应用池配置性能选项中操作超时时间设置引发的问题
- 解决串口通讯中部分串口ReadFile使用SetCommTimeouts设置超时无效的问题
- fcntl中使用O_NONBLOCK设置pipe()产生的读端非阻塞草稿
- 设置信号阻塞掩码,屏蔽特定信号
- 【VC++ 中使用ADO操作数据库学习笔记】 基础环境的设置
- Winsock例子代码:初始化、阻塞/非阻塞、超时设置、select等
- 如何在套接字IO操作上设置超时机制
- 使用信号实现超时
- 由sys用户通过查询与锁相关的视图来了解锁,了解阻塞会话与被阻塞会话的sid、serial#、用户名及其所使用的DML操作语句。
- jquery之操作元素属性和特性(设置特性值,attr(name,value),attr(attributes)方法的使用)
- 使用SQL Server代理设置SQL Server数据库定时操作http://www.xjcncn.com/school/data/mssql/200706/1359.html