并行计算
-
硬件定时器是计算机系统中的一个重要组件,由时钟源和可编程计数器组成。时钟源通常是晶体振荡器,驱动计数器以固定频率生成定时器中断。
-
实时时钟(RTC):用于提供系统的实时时间和日期信息,通常由小型备用电池供电,即使计算机关闭也能继续运行。
-
可编程间隔定时器(PIT):是一个独立于CPU的硬件定时器,可编程以提供毫秒级的定时器刻度。
-
多核CPU中的本地定时器:每个核都有自己的本地定时器,由CPU时钟驱动,可用于测量各核心的执行时间。
-
高分辨率定时器:通常用时间戳计时器(TSC)实现,提供高精度的时间测量。
CPU操作
-
CPU拥有多个寄存器,包括程序计数器(PC)、状态寄存器(SR)、堆栈指针(SP)和通用寄存器。
-
PC (Program Counter):指向下一条要执行的指令的地址。
-
SR (Status Register):包含有关CPU当前状态的信息,如操作模式、中断掩码和条件码。
-
SP (Stack Pointer):指向当前堆栈的栈顶。
时间相关系统调用
-
time系统调用:用于获取当前时间,以秒为单位。可通过参数传递给应用程序。
-
times系统调用:用于获取进程的执行时间信息,包括用户模式时间和系统模式时间。结果存储在
tms
结构中。
间隔定时器
-
ITIMER_REAL:在到期时生成
SIGALRM
信号。 -
ITIMER_VIRTUAL:在用户模式下执行时减少,到期时生成
SIGVTALRM
信号。 -
ITIMER_PROF:在用户模式和系统模式下执行时减少,通常与
ITIMER_VIRTUAL
结合使用,用于分析用户模式和内核模式下的执行时间,生成SIGPROF
信号。
命令行工具
-
date
:用于打印或设置系统的日期和时间。 -
time
:报告进程在用户模式和系统模式下的执行时间。 -
hwclock
:查询和设置硬件时钟(RTC),也可以通过BIOS来完成。
这些知识点对于理解并行计算和处理与时间相关的任务非常重要。硬件定时器和系统调用可帮助操作系统和应用程序精确测量时间,从而支持定时、调度和性能分析。
实践过程
通过gettimeofday()
获取系统时间
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
struct timeval t;
int main() {
gettimeofday(&t, NULL);
printf("sec=%ld usec=%ld\n", t.tv_sec, t.tv_usec);
printf((char *)ctime(&t.tv_sec));
}
通过settimeofday()
设置系统时间
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
struct timeval t;
int main() {
int r;
t.tv_sec = 123456789;
t.tv_usec = 0;
r = settimeofday(&t, NULL);
if (!r) {
printf("settimeofday() failed\n");
exit(1);
}
gettimeofday(&t, NULL);
printf("sec=%ld usec=%ld\n", t.tv_sec, t.tv_usec);
printf("%s", ctime(&t.tv_sec));
}
使用time
系统调用
#include <stdio.h>
#include <time.h>
time_t start, end;
int main() {
int i;
start = time(NULL);
printf("start=%ld\n", start);
for (i = 0; i < 20201307; i++)
end = time(NULL);
printf("end=%ld time=%ld\n", end, end - start);
}
sigaction
使用示例
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
//#include <siginfo.h>
void handler(int sig, siginfo_t *siginfo, void *context) {
printf("handler: sig=%d from PID=%d UID=%d\n", sig, siginfo->si_pid, siginfo->si_uid);
}
int main(int argc, char *argv[]) {
struct sigaction act;
memset(&act, 0, sizeof(act));
act.sa_sigaction = &handler;
act.sa_flags = SA_SIGINFO;
sigaction(SIGTERM, &act, NULL);
printf("proc PID=%d looping\n", getpid());
printf("Enter 'kill PID' to send SIGTERM signal to it\n");
while (1) {
sleep(10);
}
}