免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2413 | 回复: 4
打印 上一主题 下一主题

当recvfrom遇到alarm [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-04-25 15:31 |只看该作者 |倒序浏览
我在写一个简化的link-state router的模拟,现在的情况是,需要每秒钟执行一个checking routine,整个过程中都要用recvfrom来接受数据包。把程序简化之后大致是这个样子:


  1. #include <signal.h>
  2. #include <sys/socket.h>
  3. #include <netinet/in.h>
  4. #include <arpa/inet.h>
  5. #include <unistd.h>
  6. #include <sys/types.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>

  10. void sig_alrm(int signo) {
  11.     static int cnt = 0;
  12.     printf("Alarm handled: %d\n", ++cnt);
  13.     alarm(1);
  14. }

  15. int main() {
  16.     int sockfd, yes = 1;
  17.     struct sockaddr_in my_addr, their_addr;
  18.     unsigned addr_len;
  19.         int nbytes;
  20.         char packet[1000];

  21.     signal(SIGALRM, sig_alrm);
  22.         alarm(1);

  23.         sockfd = socket(PF_INET, SOCK_DGRAM, 0);
  24.         if (sockfd == -1) {
  25.                 perror("socket");
  26.                 exit(1);
  27.         }

  28.         if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
  29.                 perror("setsockopt");
  30.                 exit(1);
  31.         }

  32.         my_addr.sin_family = AF_INET;
  33.         my_addr.sin_port = htons(50001);
  34.         my_addr.sin_addr.s_addr = INADDR_ANY;
  35.         memset(&my_addr.sin_zero, 0, sizeof(my_addr.sin_zero));
  36.         if(bind(sockfd, (struct sockaddr*)(&my_addr), sizeof(struct sockaddr)) == -1) {
  37.                 perror("bind");
  38.                 exit(1);
  39.         }

  40.         addr_len = sizeof(struct sockaddr);
  41.         while(1) {
  42.                 if ((nbytes = recvfrom(sockfd, &packet, sizeof(packet), 0, (struct sockaddr*)&their_addr, &addr_len)) == -1) {
  43.                         perror("recvfrom");
  44.                         exit(1);
  45.                 }
  46.         }

  47.         return 0;
  48. }

复制代码


但在Solaris 10 x86 上运行的时候,总是如下:
Alarm handled: 1
recvfrom: Interrupted system call
就退出了。

我觉得可能是recvfrom在block了进程,等待数据包的时候,出现了SIGALRM,导致程序出错。如果真是这样,有什么办法可以解决呢?如果真的没有办法让recvfrom和alarm共存的话,我想到的一个解决办法是把那个定时运行的routine放到另一个thread里去。大家有什么建议呢?
谢谢。

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
2 [报告]
发表于 2006-04-25 15:40 |只看该作者
使用sigaction,在struct sigaction结构中,
有一个sa_flags,设置它为SA_RESTART,
这样就可以重起被中断的系统调用。
看来sun solaris 上的 signal默认是不重起系统调用的,
而linux上可以。
man sigaction

论坛徽章:
0
3 [报告]
发表于 2006-04-25 15:48 |只看该作者
谢谢:)
刚才无意中在apue上的10.5节找到了答案。不得不说apue是本宝书……

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
4 [报告]
发表于 2006-04-25 15:52 |只看该作者
恩,APUE的作者在写那本书的时候都建议以后不要再继续使用signal这个函数,现在就更不要使用这个函数了

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
5 [报告]
发表于 2006-04-25 15:57 |只看该作者
原帖由 angelo23 于 2006-4-25 15:48 发表
谢谢:)
刚才无意中在apue上的10.5节找到了答案。不得不说apue是本宝书……

呵呵,我所知道的这些也是来自APUE,
怀念Stevens!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP