Ori*_*ari 5 c macos timer ios macos-sierra
我想知道如何在 macOS / iOS 中创建计时器。在 linux 中,您可以使用 time.h 类的 timer_create() 函数创建它,但在 macOS / iOS 中,此函数不存在。
类似于 NSTimer (objective-c) 但在 C 中。
谢谢
在上一个答案中更新了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)
您可以将 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)