ualarm()没有在android版本的libc中实现,bionic(检查Bionic unistd.h)。而且,ualarm()已经过时。
我正在android ndk上移植一个应用程序,因此我需要一个类似于ualarm(999999999999)的程序,即周期性(每秒)发送一个sigalrm的程序。
可能是因为timer_create()?似乎是implemented in Bionic。但是手册页中的例子并不简单…
我要移植到android(ndk)的代码:

/*
 * Set a recurring 1 second timer that will call sigalrm() and switch to
 * a new channel.
 */

    act.sa_handler = sigalrm_handler;
    sigaction (SIGALRM, &act, 0);
    ualarm(CHANNEL_INTERVAL, CHANNEL_INTERVAL);
    change_channel(1);

/* Whenever a SIGALRM is thrown, go to the next 802.11 channel */
void sigalrm_handler(int x)
{
    next_channel();
}

最佳答案

好的,创建计时器是关键。可惜没人及时用例子回答。
我通过简化this answer构建了这个代码。

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>

// Handler that will be called every its.it_value.tv_sec seconds + its.it_value.tv_nsec nanoseconds until you kill the timer
static void handler(int sig, siginfo_t *si, void *uc)
{
        printf("Caught signal %d from timer\n", sig);
}

int main(int argc, char *argv[])
{
    struct sigevent sev;
    struct itimerspec its;
    sigset_t mask;
    struct sigaction sa;
    timer_t timerid;

    // Define sigaction: handler
    sa.sa_flags = SA_SIGINFO;
    sa.sa_sigaction = handler;
    sigemptyset(&sa.sa_mask);
    sigaction(SIGUSR1, &sa, NULL);

    // Define sigevent
    sev.sigev_notify = SIGEV_SIGNAL;
    sev.sigev_signo = SIGUSR1;

    // Create the timer
    timer_create(CLOCK_REALTIME, &sev, &timerid);
    its.it_value.tv_sec = 1;
    its.it_value.tv_nsec = 0;
    its.it_interval.tv_sec = its.it_value.tv_sec;
    its.it_interval.tv_nsec = its.it_value.tv_nsec;
    timer_settime(timerid, 0, &its, NULL);

    // Sleeps (100sec) is aborted: its default behavior is to wake up when a signal is received (1sec)
    // So we sleep again to properly see the next signal in this example.
    // That's just for the example so that the process doesn't terminate.
    sleep(100); sleep(100); sleep(100); sleep(100); sleep(100); sleep(100);
    exit(EXIT_SUCCESS);
}

使用ualarm(0,0)禁用周期计时器。在争论中不需要传递计时器。但是随着时间删除,我们需要这个计时器引用。因此,必须修改代码以记住计时器引用以禁用它。
因此,如果需要,通过引用传递计时器:
some_function(..., &timerid);
void some_function(..., timer_t *timerid)

要禁用计时器:
timer_delete(timerid);

还要注意,ualarm使用sigalrm信号。在这段代码中,我们使用的是sigusr1。
sigalrm、sigvtalrm和sigprof
当调用前面的报警设置中指定的时间限制时,sigalrm、sigvtalrm和sigprof信号被发送到进程
函数(如setitimer)失效。sigalrm在真实或
时钟时间过去了。当
过程结束。当进程和
由系统代表进程通过。
Sigusr1和Sigusr2
sigusr1和sigusr2信号被发送到进程以指示用户定义的条件。
如果使用多个都使用sigusr1的计时器,则可能存在计时器冲突。检查original answer以处理多个计时器,所有计时器都使用sigusr1。

10-07 13:16