在 macOS 中创建 C 计时器

Ori*_*ari 5 c macos timer ios macos-sierra

我想知道如何在 macOS / iOS 中创建计时器。在 linux 中,您可以使用 time.h 类的 timer_create() 函数创建它,但在 macOS / iOS 中,此函数不存在。

类似于 NSTimer (objective-c) 但在 C 中。

谢谢

b d*_*nan 7

在上一个答案中更新了Grand Central Dispatch计时器(Apple 页面)的链接后,我为两个计时器创建了一些示例代码。应该注意的是,这适用于 FreeBSD 和 MacOS,但不适用于 Linux(不支持 GCD)。该示例创建了两个事件计时器,一个触发 0.2 秒,另一个触发 0.5 秒,总共 20 次。在执行开始之前存在 1 秒延迟。sleep()不使用这些功能。

#include <dispatch/dispatch.h>
#include <stdio.h>
#include <stdlib.h>

int i = 0;
dispatch_queue_t queue;
dispatch_source_t timer1;
dispatch_source_t timer2;


void sigtrap(int sig)
{
    dispatch_source_cancel(timer1);
    dispatch_source_cancel(timer2);
    printf("CTRL-C received, exiting program\n");
    exit(EXIT_SUCCESS);
}

void vector1(dispatch_source_t timer)
{
        printf("a: %d\n", i);
        i++;
        if (i >= 20) 
        {
            dispatch_source_cancel(timer);
        }   
}
void vector2(dispatch_source_t timer)
{
        printf("b: %d\n", i);
        i++;
        if (i >= 20)  //at 20 count cancel the 
        {
            dispatch_source_cancel(timer);
        }   
}

int main(int argc, const char* argv[]) {

    signal(SIGINT, &sigtrap);   //catch the cntl-c
    queue = dispatch_queue_create("timerQueue", 0);

    // Create dispatch timer source
    timer1 = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    timer2 = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    
    // Set block for dispatch source when catched events
    dispatch_source_set_event_handler(timer1, ^{vector1(timer1);});
    dispatch_source_set_event_handler(timer2, ^{vector2(timer2);});

    // Set block for dispatch source when cancel source
    dispatch_source_set_cancel_handler(timer1, ^{
        dispatch_release(timer1);
        dispatch_release(queue);
        printf("end\n");
        exit(0);
    });
    dispatch_source_set_cancel_handler(timer2, ^{
        dispatch_release(timer2);
        dispatch_release(queue);
        printf("end\n");
        exit(0);
    }); 

    dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC); // after 1 sec

    // Set timer
    dispatch_source_set_timer(timer1, start, NSEC_PER_SEC / 5, 0);  // 0.2 sec
    dispatch_source_set_timer(timer2, start, NSEC_PER_SEC / 2, 0);  // 0.5 sec
    printf("start\n");    
    dispatch_resume(timer1);
    dispatch_resume(timer2);
    while(1)
    {
        ;;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)


n3w*_*3wb 4

您可以将 pthreads 用于 macOS,并结合睡眠和时间

 typedef struct Timer {
        void (*fn)(void);
        bool (*timer_delegate)(pthread_t, unsigned int, unsigned int);
        unsigned int seconds;
 } Timer;

void* timer_run(void *t) {

    unsigned int start_time = time(NULL);
    while(1) {
        Timer tmr = *((Timer *) t);
        bool should_kill_thread = tmr.timer_delegate(pthread_self(), start_time, time(NULL));
        if (should_kill_thread) pthread_cancel(pthread_self());
        tmr.fn();

        sleep(tmr.seconds);
    }
}

bool should_kill_thread(pthread_t t, unsigned int start_time, unsigned int utime_new) {
    printf("the start time was %d and the new time is %d \n", start_time, utime_new);

    if (utime_new - start_time >= 9) {
        return true;
    }

    return false;
}

void hello_world() {
    printf("%s\n", "Hello, World!");
}

int main(int argc, char const *argv[])
{
    pthread_t t1;
    Timer args;
    args.fn = &hello_world;
    args.timer_delegate = should_kill_thread;
    args.seconds = 1; // call every 1 second

    int id = pthread_create(&t1, NULL, timer_run, &args);
    if (id) {
       printf("ERROR; return code from pthread_create() is %d\n", id);
       exit(EXIT_FAILURE);
    }

    pthread_join(t1, NULL); // blocks main thread
    printf("%s\n", "DONE"); // never reached until t1 is killed
    return 0;
}
Run Code Online (Sandbox Code Playgroud)