其他分享
首页 > 其他分享> > 20191330雷清逸 学习笔记8

20191330雷清逸 学习笔记8

作者:互联网

20191330 雷清逸 学习笔记8(第五章)

一、知识点归纳以及自己最有收获的内容

知识点归纳

摘要

本章讨论了定时器和定时器服务;介绍了硬件定时器的原理和基于Intel x86的 PC 中的硬件定时器;讲解了 CPU操作和中断处理;描述了Linux中与定时器相关的系统调用、库函数和定时器服务命令;探讨了进程间隔定时器、定时器生成的信号,并通过示例演示了进程间隔定时器。编程项目的目的是要在一个多任务处理系统中实现定时器、定时器中断和间隔定时器。多任务处理系统作为—个Linux进程运行,该系统是 Linux进程内并发任务的一个虚拟 CPU。Linux 进程的实时模式间隔定时器被设计为定期生成SIGALRM信号,充当虚拟CPU的定时器中断,虚拟CPU使用SIGALRM信号捕捉器作为定时器的中断处理程序。该项目可让读进程通过定时器队列实现任务间隔定时器,还可让读进程使用Linux 信号掩码来实现临界区,以防止各项任务和中断处理程序之间出现竞态条件。

最有收获的部分

硬件定时器

个人计算机定时器

4.高分辨率定时器:

(1)大多数电脑都有一个时间戳定时器(TSC),由系统时钟驱动。

CPU操作

中断处理

时钟服务函数

时钟服务可通过系统调用、库函数和用户级命令调用。

以下是Linux的一些基本时钟服务函数:

#include <sys/time.h>
int gettimeofday(struct timeval *tv,struct timezone *tz);
int settimeofday(const struct timeval *tv,const struct timezone *tz);

这是对Linux内核的系统调用;settimeofday()函数用于设置当前时间;它可以通过库函数ctime(&time)转化为日历形式。

time_t time(time_t *t)

该函数会以为单位返回当前时间

time系统调用具有一定的局限性,只提供以为单位的分辨率,而不是以微秒为单位。

clock_t times(struct tms *buf)

该函数可用于获取某进程的具体执行时间。它将进程时间存储在struct tms buf中

间隔定时器

Linux为每个进程提供了三种不同类型的间隔计时器。

间隔计时器由setitimer()系统调用创建。getitimer()系统调用返回间隔定时器的状态。

REAL模式间隔定时器

二、问题与解决思路

问题:Linux下的定时器有sleep,usleep,nanosleep等等,它们有什么区别呢?

答:经过对相关资料的查阅,发现它们的区别如下:

sleep()和nanosleep()都是使进程睡眠一段时间后被唤醒,但是二者的实现完全不同。
Linux中并没有提供系统调用sleep(),sleep()是在库函数中实现的,它是通过调用alarm()来设定报警时间,调用sigsuspend()将进程挂起在信号SIGALARM上,sleep()只能精确到秒级上。

nanosleep()则是Linux中的系统调用,它是使用定时器来实现的,该调用使调用进程睡眠,并往定时器队列上加入一个timer_list型定时器,time_list结构里包括唤醒时间以及唤醒后执行的函数,通过nanosleep()加入的定时器的执行函数仅仅完成唤醒当前进程的功能。系统通过一定的机制定时检查这些队列(比如通过系统调用陷入核心后,从核心返回用户态前,要检查当前进程的时间片是否已经耗尽,如果是则调用schedule()函数重新调度,该函数中就会检查定时器队列,另外慢中断返回前也会做此检查),如果定时时间已超过,则执行定时器指定的函数唤醒调用进程。当然,由于系统时间片可能丢失,所以nanosleep()精度也不是很高。

alarm()也是通过定时器实现的,但是其精度只精确到秒级,另外,它设置的定时器执行函数是在指定时间向当前进程发送SIGALRM信号。

三、实践内容与截图,代码链接

实践内容为书本P162-163页的示例5.1,示例5.2及示例5.3

#include <stdio.h>
#include <stdlib.h>
#include <sys/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));
}

实践截图如下:

#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));
}

实践截图如下:

#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<123456789;i++)
	end = time(NULL);
	printf("end =%ld time=%ld\n",end,end-start);
}

实践截图如下:

标签:调用,中断,笔记,20191330,定时器,清逸,Linux,进程,CPU
来源: https://www.cnblogs.com/leo-skr/p/15505637.html