V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
ReputationZh
V2EX  ›  Linux

循环执行一个函数,定时退出,不能在函数外部添加代码,应该怎么做?

  •  
  •   ReputationZh · 2020-09-16 18:58:54 +08:00 · 2286 次点击
    这是一个创建于 1548 天前的主题,其中的信息可能已经有所发展或是发生改变。

    可以将题目理解成这样: while(1) { //不允许添加代码 Fun(); //不允许添加代码 }

    要求函数执行 15s 后退出。 函数执行速度很快,可能会在 1us~10us 左右。

    我在函数内定义 static clock_t,但是发现 clock 遇到阻塞后不会计算时间,于是我放弃了这个方案。 后来使用 time_t,发现 time_t 的精度为秒,也放弃了。

    大佬们救救孩子吧。

    11 条回复    2020-09-17 14:39:04 +08:00
    anytk
        1
    anytk  
       2020-09-16 20:53:19 +08:00 via Android
    clock_gettime
    Chowe
        2
    Chowe  
       2020-09-16 23:39:35 +08:00 via iPhone
    休眠算吗?
    l12ab
        3
    l12ab  
       2020-09-16 23:56:48 +08:00 via iPhone
    换个思路,你这就是每隔 15 秒执行一次,所以定时触发
    nvkou
        4
    nvkou  
       2020-09-17 00:01:53 +08:00 via Android
    看起来 fun 是无返回的啊。多线程处理?守护线程定时发起任务和终止任务。
    nightwitch
        5
    nightwitch  
       2020-09-17 00:04:05 +08:00
    https://www.man7.org/linux/man-pages/man2/timer_create.2.html

    创建一个 timer,在 while 的前面设置 timer 的时间。时间到了会给进程发 signal,你就从函数里面出来了。
    nightwitch
        6
    nightwitch  
       2020-09-17 00:08:49 +08:00
    https://www.man7.org/linux/man-pages/man3/ualarm.3.html
    如果 us 级的精度够用的话用 ualarm 的 api 会简单点
    yazoox
        7
    yazoox  
       2020-09-17 08:24:39 +08:00
    @nightwitch 兄弟,你的意思是,类似下面这样的么?
    function A() {

    // create a timer, it will be triggered 15s later, and then exit function A such as `return;`, etc.

    while(1) {
    fun()
    }

    }
    iceheart
        8
    iceheart  
       2020-09-17 08:46:57 +08:00 via Android
    clock_gettime
    gettimeofday
    nightwitch
        9
    nightwitch  
       2020-09-17 10:49:44 +08:00
    @yazoox 进程收到信号以后会直接从正在执行的函数里面跳到信号处理函数,大概类似这样吧。

    volatile bool flag = True // volatile is necessary
    void sighandler(int signum) {
    flag=False;
    }

    // set a timer, flag will be false when timer expires
    while(flag)
    {
    func(); //func shoule be async-signal-safe
    }
    ReputationZh
        10
    ReputationZh  
    OP
       2020-09-17 13:06:07 +08:00
    ```c
    int fun()
    {
    int ret = -1;

    static uint64_t RunTime = 0;
    struct timeval tvBegin = {0, 0};
    struct timeval tvEnd = {0, 0};

    do
    {
    gettimeofday(&tvBegin, NULL);
    if (RunTime > 50000000)
    {
    dprint("Timeout.");
    RunTime = 0;
    ret = 0;
    break;
    }
    usleep(1);
    gettimeofday(&tvEnd, NULL);
    RunTime += (tvEnd.tv_sec * 10000000 + tvEnd.tv_usec) - (tvBegin.tv_sec * 10000000 + tvBegin.tv_usec);
    } while (0);

    return ret;
    }

    int main(int argc, char const *argv[])
    {
    int ret = -1;
    while (ret != 0)
    {
    ret = fun();
    }
    return 0;
    }
    ```

    目前我是这么做的…
    TomVista
        11
    TomVista  
       2020-09-17 14:39:04 +08:00
    新开一个线程跑这个 while(1),到点了,杀了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2285 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 15:52 · PVG 23:52 · LAX 07:52 · JFK 10:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.