首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C替代signal() + alarm()

C替代signal() + alarm()
EN

Stack Overflow用户
提问于 2009-10-11 20:44:26
回答 6查看 2.7K关注 0票数 3

我正在构建一些FastCGI应用程序,这让我有点困扰,因为lighttpd没有在它们空闲后关闭它们,所以我试图让它们自己关闭。

我试着用

代码语言:javascript
复制
signal(SIGALRM, close);
alarm(300);

并让close函数执行exit(0),这几乎可以很好地工作。

问题是每次主程序循环运行时都会调用close函数(我在每个循环中调用alarm(300)来重置它)。我已经阅读了alarm()的手册页,似乎使用相同的值多次调用它并不会触发SIGALRM,所以我假设Lighttpd正在发送警报信号。

最大的问题!有没有办法在特定的时间间隔后运行一个方法,并使该时间间隔在没有SIGALRM的情况下是可重置的?如果我也能有多个闹钟就好了。

到目前为止,整个应用程序如下:

代码语言:javascript
复制
#include <stdlib.h>
#include <stdarg.h>
#include <signal.h>
#include "fcgiapp.h"

FCGX_Stream     *in, *out, *err;
FCGX_ParamArray envp;
int calls = 0;

void print(char*, ...);
void close();

int main(void)
{
        // If I'm not used for five minutes, leave
        signal(SIGALRM, close);

        int reqCount = 0;

        while (FCGX_Accept(&in, &out, &err, &envp) >= 0)
        {
                print("Content-type: text/plain\r\n\r\n");

                int i = 0;
                char **elements = envp;
                print("Environment:\n");
                while (elements[i])
                        print("\t%s\n", elements[i++]);

                print("\n\nDone. Have served %d requests", ++reqCount);
                print("\nFor some reason, close was called %d times", calls);

                alarm(300);
        }

        return 0;
}

void print(char *strFormat, ...)
{
        va_list args;
        va_start(args, strFormat);
        FCGX_VFPrintF(out, strFormat, args);
        va_end(args);
}

void close()
{
        calls++;
//      exit(0);
}
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2009-10-12 12:52:25

最好的方法是:添加一个线程,这样你就可以删除信号和告警,并同步线程和你的主代码(主线程)。

票数 2
EN

Stack Overflow用户

发布于 2017-12-12 12:19:47

我可能会使用POSIX计时器。定时器不必使用信号。你可以选择完全不通知,引发一个信号,或者作为一个新线程运行一个函数(我会这样做,因为它不会干扰fastcgi)。

确保包含<signal.h><time.h>,并链接到-lrt

首先,我会填写你的sigevent结构:

代码语言:javascript
复制
struct sigevent myTimerSignal = {
    .sigev_notify = SIGEV_THREAD,
    .sigev_notify_function = close //Make sure you change your function declaration to close(union sigval), you do not need to use the sigval unless you store data in your event too
};

现在创建您的计时器:

代码语言:javascript
复制
timer_t myTimer;
if(timer_create(CLOCK_REALTIME, &myTimerSignal, &myTimer)){
    //An error occurred, handle it
}

让我们武装它,它将在300秒内在一个新线程中调用close():

代码语言:javascript
复制
struct itimerspec timeUntilClose = {
    .it_value = {
        .tv_sec = 300 //300 seconds
    }
};

if(timer_settime(myTimer, 0, &timeUntilClose, NULL)){
    //Handle the error
}

现在,您应该有一个定时器,可以在300秒后停止程序。我知道我可能会迟到,但我希望这对未来的读者有所帮助。

票数 1
EN

Stack Overflow用户

发布于 2009-10-11 21:07:55

也许你可以用另一个函数包装close函数,这个函数将首先调用sleep()?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1551722

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档