当我使用for带有uint64_t作为计数器的循环时,它会永远被卡住,即使条件似乎已经明确定义.
攻击MCVE
#include <stdio.h>
#include <inttypes.h>
int main() {
uint64_t i;
for (i = 15; i >= 0; i--) { printf("%"PRIu64" ", i); }
return 0;
}
Run Code Online (Sandbox Code Playgroud)
部分输出
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 18446744073709551615 18446744073709551614 18446744073709551613 18446744073709551612 18446744073709551611 18446744073709551610 18446744073709551609 18446744073709551608 18446744073709551607 18446744073709551606 18446744073709551605 18446744073709551604 18446744073709551603 18446744073709551602 18446744073709551601 18446744073709551600 18446744073709551599 18446744073709551598 18446744073709551597 18446744073709551596 18446744073709551595 18446744073709551594 18446744073709551593 18446744073709551592 18446744073709551591 18446744073709551590 18446744073709551589 18446744073709551588 18446744073709551587 18446744073709551586 18446744073709551585 18446744073709551584 …Run Code Online (Sandbox Code Playgroud) TL;DR我需要用 C 语言模拟一个计时器,允许并发写入和读取,同时保持 60 Hz 的恒定递减(不完全准确,但大致准确)。它将成为 Linux CHIP8 模拟器的一部分。使用具有共享内存和信号量的基于线程的方法会引发一些准确性问题,以及取决于主线程如何使用计时器的竞争条件。
设计和实现这种计时器的最佳方法是什么?
我正在用 C 语言逐个模块地编写一个 Linux CHIP8 解释器,以便深入了解仿真的世界。
我希望我的实现尽可能准确地符合规范。在这方面,计时器已被证明对我来说是最困难的模块。
以延迟计时器为例。在规范中,它是一个“特殊”寄存器,最初设置为 0。有特定的操作码可以向寄存器设置值并从寄存器中获取值。
如果寄存器中输入的值不为零,它将自动开始以 60 Hz 的频率递减,一旦达到零就停止。
我对其实施的想法包括以下内容:
使用辅助线程,通过使用以接近 60 Hz 的频率自动进行递减nanosleep()。我fork()暂时用来创建线程。
使用共享内存 viammap()来分配定时器寄存器并在其上存储其值。这种方法允许辅助线程和主线程读取和写入寄存器。
使用信号量来同步两个线程的访问。我使用sem_open()和 来创建它,并sem_wait()分别sem_post()锁定和解锁共享资源。
下面的代码片段说明了这个概念:
void *p = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
/* Error checking here */
sem_t *mutex = sem_open("timersem", O_CREAT, O_RDWR, 1);
/* Error checking and unlinking */
int *val = …Run Code Online (Sandbox Code Playgroud)