1.linuxtimer
2.Linux时间子系统之:时钟源
3.linux中如何触发SIGVTALRM信号
4.盘一盘Linux内核中ns级别的计x计高精度计时方法
5.linux crontab命令详解
linuxtimer
cè¯è¨å¦ä½å å ¥æ¶éï¼cè¯è¨æ¶éç¨åºä»£ç å¦ä¸ï¼
#includewindows.h>
#includemath.h>
#defineID_TIMER1//计æ¶å¨ID
#defineTWOPI(2*3.)
LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);
intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTRszCmdLine,intiCmdShow)
{
staticTCHARszAppName=TEXT("Clock");
HWNDhwnd;
MSGmsg;
WNDCLASSwndclass;
wndclass.cbClsExtra=0;
wndclass.cbWndExtra=0;
wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wndclass.hInstance=hInstance;
wndclass.lpfnWndProc=WndProc;
wndclass.lpszClassName=szAppName;
wndclass.lpszMenuName=NULL;
wndclass.style=CS_HREDRAW|CS_VREDRAW;
if(!RegisterClass(wndclass))
{
MessageBox(NULL,TEXT("ThisprogramrequiresWindows
T"),szAppName,MB_ICONERROR);
return0;
}
hwnd=CreateWindow(szAppName,TEXT("AnalogClock"),WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
ShowWindow(hwnd,iCmdShow);
UpdateWindow(hwnd);
while(GetMessage(msg,NULL,0,0))
{
TranslateMessage(msg);
DispatchMessage(msg);
}
returnmsg.wParam;
}
voidSetsotropic(HDChdc,intcxClient,intcyClient)
{
SetMapMode(hdc,MM_ISOTROPIC);
SetWindowExtEx(hdc,,,NULL);
SetViewportExtEx(hdc,cxClient/2,-cyClient/2,NULL);
SetViewportOrgEx(hdc,cxClient/2,cyClient/2,NULL);
}
voidRotatePoint(POINTpt,intiNum,intiAngle)
{
inti;
POINTptTemp;
for(i=0;iiNum;i++)
{
ptTemp.x=(int)(pt.x*cos(TWOPI*iAngle/)+pt.y*sin(TWOPI*iAngle/));
ptTemp.y=(int)(pt.y*cos(TWOPI*iAngle/)+pt.x*sin(TWOPI*iAngle/));
pt=ptTemp;
}
}
voidDrawClock(HDChdc)
{
intiAngle;
POINTpt;
for(iAngle=0;iAngle;iAngle+=6)
{
pt.x=0;
pt.y=;
RotatePoint(pt,1,iAngle);
pt.x=pt.y=iAngle%5?:;
pt.x-=pt.x/2;
pt.y-=pt.y/2;
pt.x=pt.x+pt.x;
pt.y=pt.y+pt.y;
SelectObject(hdc,GetStockObject(BLACK_BRUSH));
Ellipse(hdc,pt.x,pt.y,pt.x,pt.y);
}
}
voidDrawHands(HDChdc,SYSTEMTIME*pst,BOOLfChange)
{
staticPOINTpt={ 0,-,,0,0,,-,0,0,-,0,-,,0,0,,-,0,0,-,0,0,0,0,0,0,0,0,0,};
inti,iAngle;
POINTptTemp;
iAngle=(pst->wHour*)%+pst->wMinute/2;
iAngle=pst->wMinute*6;
iAngle=pst->wSecond*6;
memcpy(ptTemp,pt,sizeof(pt));
for(i=fChange?0:2;i3;i++)
{
RotatePoint(ptTemp,5,iAngle);
Polyline(hdc,ptTemp,5);
}
}
LRESULTCALLBACKWndProc(HWNDhwnd,UINTmessage,WPARAMwParam,LPARAMlParam)
{
staticintcxClient,cyClient;
staticSYSTEMTIMEstPrevious;
BOOLfChange;
HDChdc;
PAINTSTRUCTps;
SYSTEMTIMEst;
switch(message)
{
caseWM_CREATE:
SetTimer(hwnd,ID_TIMER,,NULL);
GetLocalTime(st);
stPrevious=st;
return0;
caseWM_SIZE:
cxClient=LOWORD(lParam);
cyClient=HIWORD(lParam);
return0;
caseWM_TIMER:
GetLocalTime(st);
fChange=st.wHour!=stPrevious.wHour||st.wMinute!=stPrevious.wMinute;
hdc=GetDC(hwnd);
Setsotropic(hdc,cxClient,cyClient);
SelectObject(hdc,GetStockObject(WHITE_PEN));
DrawHands(hdc,stPrevious,fChange);
SelectObject(hdc,GetStockObject(BLACK_PEN));
DrawHands(hdc,st,TRUE);
stPrevious=st;
return0;
caseWM_PAINT:
hdc=BeginPaint(hwnd,ps);
Setsotropic(hdc,cxClient,cyClient);
DrawClock(hdc);
DrawHands(hdc,stPrevious,TRUE);
EndPaint(hwnd,ps);
return0;
caseWM_DESTROY:
KillTimer(hwnd,ID_TIMER);
PostQuitMessage(0);
return0;
}
returnDefWindowProc(hwnd,message,wParam,lParam);
}
Cè¯è¨æ¯ä¸é¨éç¨è®¡ç®æºç¼ç¨è¯è¨ï¼åºç¨å¹¿æ³ãCè¯è¨ç设计ç®æ æ¯æä¾ä¸ç§è½ä»¥ç®æçæ¹å¼ç¼è¯ãå¤çä½çº§åå¨å¨ã产çå°éçæºå¨ç 以åä¸éè¦ä»»ä½è¿è¡ç¯å¢æ¯æ便è½è¿è¡çç¼ç¨è¯è¨ã尽管Cè¯è¨æä¾äºè®¸å¤ä½çº§å¤ççåè½ï¼ä½ä»ç¶ä¿æçè¯å¥½è·¨å¹³å°çç¹æ§ï¼ä»¥ä¸ä¸ªæ åè§æ ¼ååºçCè¯è¨ç¨åºå¯å¨è®¸å¤çµèå¹³å°ä¸è¿è¡ç¼è¯ï¼çè³å å«ä¸äºåµå ¥å¼å¤çå¨ï¼åçæºæ称MCUï¼ä»¥åè¶ çº§çµèçä½ä¸å¹³å°ã
Cè¯è¨æ¯ç±UNIXçç å¶è 丹尼æ¯Â·éå¥ï¼DennisRitchieï¼äºå¹´ç±è¯Â·æ±¤æ®éï¼KenThompsonï¼æç å¶åºçBè¯è¨çåºç¡ä¸åå±åå®åèµ·æ¥çãç®åï¼Cè¯è¨ç¼è¯å¨æ®éåå¨äºåç§ä¸åçæä½ç³»ç»ä¸ï¼ä¾å¦UNIXãMS-DOSãMicrosoftWindowsåLinuxçãCè¯è¨ç设计影åäºè®¸å¤åæ¥çç¼ç¨è¯è¨ï¼ä¾å¦C++ãObjective-CãJavaãC#çã
Linux时间子系统之:时钟源
探索Linux内核的时间奥秘:时钟源的精密构建在Linux内核的精密世界里,时钟源扮演着时间基准的时器时器角色,它像一台隐形的源码精确计时器,通过硬件计数器确保我们与时间的函数精准同步。struct clocksource是计x计这个系统的核心结构,其中的时器时器极地源码关键组件,如rating(精度,源码范围1-,函数数值越高,计x计时间精度越优)、时器时器read回调,源码以及mult和shift,函数共同构建了这个时间测量的计x计基石。rating值在1-范围内用于特殊用途,时器时器而-区间则为常规选择,源码read函数则是网页刷源码下载时间计数的窗口,mult和shift则是处理计数与频率F之间转换的魔力公式,内核采用位精度进行计算。
为了确保时间更新的稳定性和准确性,clocksource_register_hz在初始化时,通过一系列复杂的计算,确定了mult、shift的值,并为最大闲置时间设定了限制。同时,clocksource_register_scale负责性能排序和监控,而watchdog就像一个警惕的眼睛,一旦发现性能偏差超出阈值,就会标记该时钟源为不稳定状态。 在Linux启动的早期阶段,系统首先注册基于jiffies的英文在线客服源码clocksource,尽管其评级较低,但这正是基础中的基础。想要深入了解这个时钟源体系的更多细节,你可以在Linux内核源码分析学习群中发现丰富的资源。 深入理解clocksource的运作机制- clocksource_jiffies结构体,其设计为每个时钟周期提供1/HZ秒的精度,评级为1,是默认选择,除非有特定需求,否则系统会采用这个基础时钟源。
- init_jiffies_clocksource函数是初始化和注册这个时钟源的关键步骤,它确保了clocksource_jiffies的顺利启动。
- clocksource_default_clock提供了一种可选的默认时钟源,通常设置为clocksource_jiffies,但在特定场景下,java class 类源码可以被自定义以适应特定需求。
- clocksource_done_booting则在系统启动的后期,根据系统的实际情况,选择最合适的clocksource,并通知timekeeping系统进行适时的时间更新,确保系统时间的精准与一致性。
在这个看似简洁的时间管理背后,Linux内核的时钟源系统蕴含着精细的逻辑与优化,每个组件都在默默地守护着系统的稳定和准确性。深入理解这些细节,对于任何想要驾驭Linux内核的开发者来说,无疑是一把打开时间秘密的钥匙。
linux中如何触发SIGVTALRM信号
which:间歇计时器类型,有三种选择
ITIMER_REAL //数值为0,计时器的javaee编程案例源码值实时递减,发送的信号是SIGALRM。
ITIMER_VIRTUAL //数值为1,进程执行时递减计时器的值,发送的信号是SIGVTALRM。
ITIMER_PROF //数值为2,进程和系统执行时都递减计时器的值,发送的信号是SIGPROF。
value,ovalue:时间参数,原型如下
struct itimerval
{
struct timeval it_interval;
struct timeval it_value;
};
struct timeval
{
long tv_sec;
long tv_usec;
};
getitimer()用计时器的当前值填写value指向的结构体。
setitimer()将value指向的结构体设为计时器的当前值,如果ovalue不是NULL,将返回计时器原有值。
盘一盘Linux内核中ns级别的高精度计时方法
在Linux内核中,尽管系统本身和中断的存在限制了其提供ns级别的高精度计时,常规内核高精度计时器只能勉强达到us级别且误差较大。因此,在需要ns级别精确计时的场景下,需要借助其他方法。以下介绍两种针对不同处理器平台的精确计时方式:x平台和ARM平台。
### x平台下的精确计时
从Pentium开始,x平台引入了时间戳计数器(TSC),这是一个用于记录自上电启动以来CPU执行周期数的位寄存器。在每个时钟信号到来时,TSC自动加一。若CPU主频为2GHz,每条指令执行时间为0.5ns。通过读取TSC的当前值,可以计算出代码执行的时间。具体操作是在代码段的A点和B点分别读取TSC,两值相减并乘以指令周期,即可得到A点和B点间代码执行的耗时。
### ARM平台下的精确计时
对于ARM平台,虽然没有直接提供类似TSC的寄存器,但通过定时计数器实现精确计时是可行的。定时器能够提供计数和计数比较功能,计数频率由系统时钟经过分频决定,且不受系统软件影响,可以实现较高的精度。以MHz计数频率为例,每秒计数次,转换为us级别,每计数一次为ns。通过驱动程序直接访问相关寄存器,可以实现精确的计时功能。
### ARM平台的计数器使用
在ARM架构的芯片上,定时器的使用涉及频率、控制、计数等关键寄存器。通过设置计数器频率控制器(CNTFRQ_EL0)和物理计数器控制寄存器(CNTP_CTL_EL0),可以启用计数器进行精确计时。计数器在使能后开始计数,即使被停止计数,仍会继续计数直到断电。驱动程序通过死循环轮询计数寄存器,可以验证计数器的精度,并实现精确的计时功能。
### 性能监控寄存器
ARM平台还提供性能监控寄存器(Performance Monitors registers),包括性能监控控制寄存器(PMCR_EL0)、计数使能寄存器(PMCNTENSET_EL0)和周期计数寄存器(PMCCNTR_EL0)。这些寄存器主要用于CPU性能监控,但同样提供了计数功能,可以用于精确计时。通过结合性能监控单元(PMU),可以实现高级的性能监控和计时。
通过上述方法,x和ARM平台在特定场景下能够实现ns级别的精确计时,为开发者提供了灵活的计时解决方案。
linux crontab命令详解
crontab是用来定期执行程序的命令,crond进程每分钟会定期检查是否有要执行的任务,如果有要执行的任务,则自动执行该任务,Linux系统下crontab命令的任务调度分为两类,系统任务调度和用户任务调度:
1、系统任务调度:系统周期所要执行的工作,比如写缓存数据到硬盘、日志清理等;
2、用户任务调度:用户定期要执行的工作,比如用户数据备份、定时邮件提醒等。用户可以使用 crontab 工具来定制自己的计划任务。
语法:crontab [ -u user ] file
参考例子:
创建、编辑计划任务:
[root@linux ~]# crontab -e
参数:
-e 编辑该用户的计时器设置
-l 列出该用户的计时器设置
-r 删除该用户的计时器设置
-u 指定要设定计时器的用户名称
--help 显示帮助信息