Chinaunix

标题: C语言的一道计算时间的题 [打印本页]

作者: fir1983    时间: 2008-12-04 14:48
标题: C语言的一道计算时间的题

  1. void f1(){ printf("Come into f1\n");}
  2. void f2(){ printf("Come into f2\n");}
  3. int main()
  4. {
  5.     int num;
  6.     printf("Please input a number:");
  7.     /*
  8.     * 如果10秒钟内输入了数字(不考虑非法输入),接下来处理函数f1()
  9.     * 如果10秒钟内没有任何输入,接下来处理函数f2()
  10.     */
  11.    
  12.     //enter you code here;
  13.    
  14.     return 0;
  15. }
复制代码

作者: kns1024wh    时间: 2008-12-04 21:05
标题: 回复 #1 fir1983 的帖子
有条件我去测试一下
作者: crscholes    时间: 2008-12-04 23:03
用信号 alarm就行了吧
作者: fir1983    时间: 2008-12-05 09:08
原帖由 crscholes 于 2008-12-4 23:03 发表
用信号 alarm就行了吧


谢谢提醒
我去试试
作者: duanjigang    时间: 2008-12-05 09:40
原帖由 crscholes 于 2008-12-4 23:03 发表
用信号 alarm就行了吧


作者: exir    时间: 2008-12-06 12:17
信号很金贵的,alarm信号很多库函数还抢着用。能不用就不用了吧。
const int timeout = 10;
int done = time(NULL) + timeout;
while(time(NULL) > done)
{
.....
}
比设置信号还简单。
可以用gettimeofday实现一个自己的函数取代time以得到精确到纳秒的计时。
作者: MMMIX    时间: 2008-12-06 23:01
标题: 回复 #6 exir 的帖子
忙等待 通常来说不是个好主意。
作者: timespace    时间: 2008-12-06 23:34
标题: 回复 #1 fir1983 的帖子
select/poll + read(STDIN_FILENO, ...)
作者: exir    时间: 2008-12-07 10:26
原帖由 MMMIX 于 2008-12-6 23:01 发表
忙等待 通常来说不是个好主意。

大多数时候信号处理也只是设置个标记,在合适的时候去查询。和轮询差别不大。
针对这个例子,几乎完全一样。轮询中只要每次休眠个200ms,对人的输入来说
感觉不到差别,对cpu来说占用大大减少。
对标准输入进行select似乎不错,不过没试过。
作者: MMMIX    时间: 2008-12-07 14:20
原帖由 exir 于 2008-12-7 10:26 发表

大多数时候信号处理也只是设置个标记,在合适的时候去查询。和轮询差别不大。

差别不大?
作者: timespace    时间: 2008-12-07 17:10
原帖由 exir 于 2008-12-6 12:17 发表
信号很金贵的,alarm信号很多库函数还抢着用。能不用就不用了吧。

应该谨慎使用信号,alarm会和sleep,usleep,setitimer等函数的冲突,但此处不应该使用的alarm的关键是alarm把一个本应该能用简单同步处理的问题(select/poll是常用方法)转化为复杂的异步处理(通过信号处理函数)


原帖由 exir 于 2008-12-6 12:17 发表
while(time(NULL) > done)
{
.....
}

这个循环等待放在linux 2.6以前是绝对的系统性能杀手,虽然可以在while循环内部放入休眠函数来避免占用太多的CPU,但是前提必须要把标准输入设置为O_NONBLOCK

原帖由 exir 于 2008-12-6 12:17 发表
可以用gettimeofday实现一个自己的函数取代time以得到精确到纳秒的计时。

是微妙吧。POSIX clock family才能提供纳秒级,如clock_gettime

附上select实现的C++ demo,各位有兴趣可以实现诸如alarm,轮询等方式
#include <cstring>
#include <cerrno>
#include <iostream>
#include <string>

#include <unistd.h>
#include <sys/select.h>

using namespace std;

int getInput(string &in, const int timeout);

int main()
{
    string input("");
    int ret;

    ret = getInput(input, 10);
    if (ret > 0) {
        cout << "Got you: " << input << endl;
    } else if (ret == 0) {
        cout << "timeout !" << endl;
    } else {
        cout << "something wrong: " << strerror(errno) << endl;
    }

    return 0;
}

int getInput(string &in, const int timeout)
{
    fd_set rset;
    timeval tv;
    int ret;

    FD_ZERO(&rset);
    FD_SET(STDIN_FILENO, &rset);
    tv.tv_sec = timeout;
    tv.tv_usec = 0;
    ret = select(STDIN_FILENO + 1, &rset, NULL, NULL, &tv);
    if (ret > 0)
        getline(cin, in);

    return ret;
}

作者: exir    时间: 2008-12-08 23:09
试了楼上的代码才发现,输入了回车select才会检测到输入。本来还在想要是select要是
一个一个返回就麻烦多了。
我还是觉得那个循环在处理超低俗事件时很有用,尤其是之间还需要做一些其他低速动作时候,
比如显示一个倒计时。
对于每秒钟执行次数屈指可数的循环,应该没有什么负载,也应该和内核无关,怎么会联系上
内核版本呢?

还有信号处理的问题,我看过很多比较差劲的代码都是在信号处理函数里面设置一个简单的
标志,然后在主程序里面不停的查询啊查询。完全没有用到信号的好处。
针对楼主这个命题,我觉得无论用信号还是setitimer之类的函数,都不免落入这个套路。
作者: exir    时间: 2008-12-08 23:18
gettimeofday确实是微妙,有关时间的结构太多了,迷晕人。
作者: ujiangzq    时间: 2008-12-10 18:18
补充一下:
#define   E   0.000001
const int timeout = 10;
int done = time(NULL) + timeout;
while(difftime( time(NULL), done ) > E)
{
.....
}
作者: meishu    时间: 2008-12-11 17:06
非阻塞模式读标准输入




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2