linux timer机制

linux timer机制
linux timer机制

linux timer机制

一、clocksource与clockevent

Linux 2.6.16之前的系统,总是被动的接受时钟中断,然后运行中断处理程序最终可能导致调度的发生,如果实在没有任务可以运行,那么就执行idle,这也许也算一种创意,可是时钟中断还是会周期性的打破idle,然后查询有没有需要做的事情,如果没有继续idle。

这种方式没有什么问题,可是我们总是希望系统可以主动的做些事情,比如不是被动的接受中断而是主动的设置什么时候中断,因此必须将系统时钟发生中断这件事进行向上抽象,于是相应的clocksource和 clock_event_device,这两个结构体就是时钟以及时钟行为的抽象。

Clocksource好比就是一个钟表,我们需要一个钟表就是需要读出它的指针的值从而知道现在几点,就是这些,因此钟表都会有显示盘用于读数,至于钟表怎么运作,那就是钟表内部的机械原理了,记住,钟表就是用来读数的;另外我们为了害怕误事而需要闹铃,需要的是闹铃在一个时间段之后把我们唤醒,这是个事情,而这个事情不一定非要有钟表,没有钟表的闹铃就是clock_event_device。钟表和闹铃其实是两个东西,钟表为你展示某些事情,而闹铃需要你的设置,设想一个场景,你手边有一个没有闹铃的钟表,还有一个没有钟表的闹铃,这个闹铃只能设置绝对时间,然后到期振铃,你现在不知道几点,可是你要睡觉并且得到通知必须在四个小时后去参加一个聚会,那么你现在要做什么?你肯定要看看你的钟表,然后设置你的闹钟。

clocksource代表了一个时钟源,一般都会有一个计数器,其中的read回调函数就是负责读出其计数器的值,可是我们为何找不到write或者set之类的回调函数呢?这些回调函数其实不应该在closksource中,而应该在clock_event_device中。

clock_event_device的set_next_event致使系统明确的知道下一个中断什么时候到来,这其实没有什么不对,就是因为它是时钟相关的,而时钟中断在老的版本的内核里面的中断间隔也是确定的。新的内核越来越多的将硬件把手抽象给内核,或者将内核把手抽象给用户,这样的内核显得越来越成熟了,内核可以通过硬件把手操控硬件从而影响运行时的策略,而用户可以通过内核把手操控内核从而影响内核的运行时策略。内核对下面的硬件可以控制了,对上面的用户空间也提供了很多不错的操作接口,三层的联系越来越紧密但是却没有增加耦合性,实在是妙!

简言之:clocksource好比一个钟表,仅仅带read回调函数就是负责读出其计数器的值。clock_event_device好比一个不带时间显示的闹铃,其set_next_event函数使系统明确的知道下一个中断什么时候到来。

clocksource,clock_event_device这种架构解决的问题是:

- 是为了将时钟相关的代码从平台相关的代码中分离出来,

- 以便于独立修改统一管理,否则需要维护很多平台的不同的时钟处理代码,

而这些代码的逻辑大致相同

- 内核不再是被动的接受时钟中断,而是主动的设置时钟中断

- 调度行为不再依赖HZ的值,

-底层的时钟硬件处理函数不再被在start_kernel中一次性的设置,

而是被封装了,可以随时设置,新的设置方式显得更加直观。

二、hrtimer理论阐述

从上图可以看出:

1. Timekeeping(可以理解为时间测量或者计时)是内核时间管理的一个核心组成

部分。没有Timekeeping,就无法更新系统时间,维持系统“心跳”。

Timekeeping/GTOD 在使用时钟源设备的基础上也采用类似的封装实现了体系结构的无关性和通用性。hrtimer 则可以通过timekeeping 提供的接口完成定时器的更新,通过时钟事件设备提供的事件机制,完成对timer 的管理。

GTOD 是一个通用的框架,用来实现诸如设置系统时间gettimeofday 或者修改系统时间settimeofday 等工作。

2. hrtimer最终是通过clocksouce的read回调函数来读取时间的。

3. tick emulation是通过hrtimer来模拟系统tick的

4. 进程调度、jiffies等是基于hrtimer的

5. clock event是通过krtimer设置的。

具体实现:

1. 在内核运行的过程中,采用了两种timer机制(周期模式、高精度模式)

2. 周期模式,跟先前的timer机制没有本质区别

timer采用period模式,直接产生tick,周期性地产生中断,执行timer中断服务程序硬件timer的中断服务程序里面,直接执行进程时间片计算等关键任务。

3. 高精度模式:

timer采用oneshort模式

内核中会维护一个ktimer列表(其中肯定会建立一个名字叫sched_timer的ktimer节点)sched_timer起的作用就是模拟周期性的硬件timer

sched_timer的周期,就是系统的tick时间

sched_timer的function函数tick_sched_timer()就是正真的系统的tick处理函数,会执行进程时间片计算等关键任务。

当oneshort模式的timer进入中断服务程序之后,会完成以下任务:

a. 从ktimer列表找出所有到期hr定时器,直接执行其function函数

b. 规划下一次oneshort模式的timer的时间值(通过clockevent的set_next_event)

4. 周期模式、高精度模式的转换

在某个恰当的时候,内核通过hrtimer_switch_to_hres()函数从timer普通模式切换到高精度模式, 普通模式下面会将evt->event_handler设置成tick_handle_periodic(); 高精度模式下面会将evt->event_handler设置成hrtimer_interrupt()

三、移植层的代码分析

1. clock_event_device结构体

static struct clock_event_device v8timer_clockevent =

{

.name = V8TAG_TMR1,

.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,

.shift = 32,

.set_mode = v8timer_set_mode,

.set_next_event = v8timer_set_next_event,

//. event_handler =

};

注:CLOCK_EVT_FEAT_PERIODIC| CLOCK_EVT_FEAT_ONESHOT这两种timer 操作方式,是为在内核运行的过程中采用的两种timer机制(周期模式、高精

度模式)服务的。

set_mode 函数:为clock_event 用来设置下次中断触发的时间

set_next_event函数:供hrtimer的ktimer list设置定时时间用的

event_handler处理程序是在内核启动的过程中设置的

在某个恰当的时候,内核通过hrtimer_switch_to_hres()函数从timer普通模式切换到高精度模式, 普通模式下面会将evt->event_handler设置成

tick_handle_periodic(); 高精度模式下面会将evt->event_handler设置成

hrtimer_interrupt()

2. clocksource结构体

static struct clocksource v8timer_clocksource =

{

.name = V8TAG_TMR2,

.rating = 300,

.read= v8timer_get_cycles,

.mask = CLOCKSOURCE_MASK( 32 ),

.shift = 24,

.flags = CLOCK_SOURCE_IS_CONTINUOUS,

};

注:hrtimers是基于clocksource的read函数来读取当前时间的。

3. tick的中断处理函数

- struct irqaction v8timer_irq

- .name = "v8-timertick",

- .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,

- .handler = v8timer_interrupt, //timer中断处理函数

- v8timer_interrupt()

- evt->event_handler(evt); //回调函数,把中断事件传给上层处理

4. 初始化函数

- struct sys_timer v8timer

-.init = v8timer_init,

- v8timer_init()

- v8timer_clockevent_init();

-setup_irq(IRQ_TIMER1, &v8timer_irq); //注册v8timer_irq

- clockevents_register_device(&v8timer_clockevent);

- v8timer_clocksource_init();

- clocksource_register(&v8timer_clocksource);

注:这几个注册函数setup_irq、clocksource_register、clocksource_register可以

在上面的图片中得到验证。

四、周期模式下的timer机制

MACHINE_START

.timer = &v8timer

.init = v8timer_init

v8timer_clockevent_init()

setup_irq( IRQ_TIMER1, &v8timer_irq )

v8timer_irq.handler = v8timer_interrupt,

v8timer_interrupt()

evt->event_handler()

start_kernel()

tick_init()

clockevents_register_notifier(tick_notify())

//向clockevents_chain通知链注册回调函数-tick_notify

clockevents_register_device()

clockevents_do_notify(CLOCK_EVT_NOTIFY_ADD, dev);

//通知注册回调的人执行当时注册的回调函数tick_notify()

raw_notifier_call_chain(&clockevents_chain, reason, dev);

tick_notify()

tick_check_new_device()

tick_setup_device()

tick_setup_periodic()

tick_set_periodic_handler()

dev->event_handler = tick_handle_periodic;

tick_handle_periodic()

tick_periodic

do_timer /* 更新jiffies */

update_wall_time

update_process_times /* 计算进程耗时,, 重新计算调度时间片等等*/

run_local_timers() //执行所有的软件timer

clockevents_program_event()

->set_next_event //设置下一次事件(周期性的)五、hrtimer模式下的timer机制

Linux kernel运行起来后,首先以周期模式的timer工作,在某个恰当的时候,会从普通的周期模式,切换到高精度模式。这时候timer采用oneshort模式,内核中会维护一个ktimer列表(其中肯定会建立一个名字叫sched_timer的ktimer节点);

sched_timer起的作用就是模拟周期性的硬件timer;sched_timer的周期,就是系统的tick时间;sched_timer的function函数tick_sched_timer()就是正真的系统的tick 处理函数,会执行进程时间片计算等关键任务。当oneshort模式的timer进入中断服务程序之后,会完成以下任务:a. 从ktimer列表找出所有到期hr定时器,直接执行其function函数;b. 规划下一次oneshort模式的timer的时间值(通过clockevent的

set_next_event()函数)。

hrtimer_switch_to_hres

tick_init_highres

//高精度模式下面会将evt->event_handler设置成hrtimer_interrupt()

tick_switch_to_oneshot(hrtimer_interrupt);

dev->event_handler = handler;//hrtimer_interrupt

tick_setup_sched_timer //建立sched_timer,模拟周期性的硬件timer

hrtimer_init(&ts->sched_timer,CLOCK_MONOTONIC, RTIMER_MODE_ABS);

ts->sched_timer.function = tick_sched_timer;//高精度模式下模拟的tick处理函数

hrtimer_interrupt

for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++)

//找出所有到期hr定时器,直接执行

__run_hrtimer()

tick_program_event() //规划下一次定时器

tick_dev_program_event()

clockevents_program_event()

->set_next_event()

tick_sched_timer //hrtimer模拟的周期tick处理函数

update_process_times /* 计算进程耗时,, 重新计算调度时间片等等*/

兴旺小学班级管理团队激励机制(1)

庙子镇兴旺小学班级团队管理激励机制实施方案一、实施目的: 为进一步提高班级管理水平,调动教师参与班级管理工作积极性,体现班级管理团队合作精神,我校特制定班级管理激励机制实施方案。 二、组织机构 组长:尚宗林 副组长:张如林邱效俊 成员:全体教师 班级管理团队人员安排: 成员分工: 1、熟悉班级学生情况,协助班主任团结任课教师形成班级工作团队,共同分析、研究学生的思想、学习和生活状况,齐心协力,协同班主任一起关心每一位学生的健康成长。 2、班主任负责班上的日常工作,每个团队成员每天到班上协助班

主任完成日常工作的管理。 3、班级参加集体性活动,团队成员应参与组织与管理。集体性活动包括:社会实践活动、主题活动、文艺汇演、阳光体育、大扫除等学校组织的有关学生活动。班级参加集体比赛,团队要通力合作,出谋献策。 三、考核办法: 为使《班级团队管理工作》的管理落到实处,特制定如下量化细则: (一)、根据我校具体情况,把所有任课教师与相应班级组成班级管理团队,班级管理人考核得分也就是该教师的得分。 (二)、班级管理考核内容具体分为: A卫生 B晨读、写字 C两操 D课外活动(小组活动)E安全F纪律 G班级文化建设 H家校沟通 I学校大型活动及临时性工作完成情况 J其他工作 (三)、班级管理考核每周各项逐一考核,学期末汇总,取总分的考核方法进行。 1、安全工作:(15分) (1)班级全学期未出现安全事故记满分。 (2)发生事故纠纷上交由学校处理,但学校不承担费用的,每次扣1分。需学校承担费用100元以内的,每次扣2分,需学校承担费用100元以上——500元以内的,每次扣5分。发生重大事故需上报镇中心校处理的,此项记0分。

LINUX 内核的几种锁介绍

spinlock(自旋锁)、 mutex(互斥量)、 semaphore(信号量)、 critical section(临界区) 的作用与区别 Mutex是一把钥匙,一个人拿了就可进入一个房间,出来的时候把钥匙交给队列的第一个。一般的用法是用于串行化对critical section代码的访问,保证这段代码不会被并行的运行。 Semaphore是一件可以容纳N人的房间,如果人不满就可以进去,如果人满了,就要等待有人出来。对于N=1的情况,称为binary semaphore。一般的用法是,用于限制对于某一资源的同时访问。 Binary semaphore与Mutex的差异: 在有的系统中Binary semaphore与Mutex是没有差异的。在有的系统上,主要的差异是mutex一定要由获得锁的进程来释放。而semaphore可以由其它进程释放(这时的semaphore实际就是个原子的变量,大家可以加或减),因此semaphore 可以用于进程间同步。Semaphore的同步功能是所有系统都支持的,而Mutex能否由其他进程释放则未定,因此建议mutex只用于保护critical section。而semaphore则用于保护某变量,或者同步。 另一个概念是spin lock,这是一个内核态概念。spin lock与semaphore的主要区别是spin lock是busy waiting,而semaphore是sleep。对于可以sleep 的进程来说,busy waiting当然没有意义。对于单CPU的系统,busy waiting 当然更没意义(没有CPU可以释放锁)。因此,只有多CPU的内核态非进程空间,

TinyOS任务调度机制与实时调度构件设计

收稿日期:2007-05-09;修回日期:2007-07-18。 基金项目:国家863计划项目(2005AA1Z2120)。 作者简介:刘奎安(1982-),男,四川自贡人,硕士研究生,主要研究方向:无线传感器网络; 郭文生(1976-),男,辽宁铁岭人,讲师,博士研究生,主要研究方向:无线传感器网络、实时网络技术; 桑楠(1964-),男,四川营山人,教授,主要研究方向:嵌入式实时系统。 文章编号:1001-9081(2007)11-2740-03 Tiny OS 任务调度机制与实时调度构件设计 刘奎安,郭文生,桑 楠 (电子科技大学计算机科学与工程学院,成都610054) (lka10271982@sina .com ) 摘 要:Tiny OS 是一个开源的构件化操作系统,它采用构件化描述语言nes C 进行开发,主要针对资源非常有限的无线传感器网络节点而设计。分析了Tiny OS 22.x 的任务调度机制,针对其在实时应用领域的调度缺陷,设计并实现了一种软实时任务调度构件。根据构件在T OSSI M 仿真器中的验证分析,能有效增强Tiny OS 的实时性能。 关键词:无线传感器;Tiny OS;实时;构件设计;T OSSI M 中图分类号:TP316;TP311 文献标识码:A Schedule m echan is m of T i n yO S and its rea l 2ti m e schedule co m ponen t desi gn L I U Kui 2an,G UO W en 2sheng,S ANG Nan (School of Co m puter Science and Engineering,U niversity of Electronic Science and Technology of China, Chengdu S ichuan 610054,China ) Abstract:Tiny OS is an open 2s ource component operating syste m for sens or net w orks nodes that has very li m ited res ources .Tiny OS was i m p le mented in component 2devel op ing language nes C .Thr ough analyzing the schedule mechanis m of Tiny OS 22.x,a s oft real 2ti m e scheduler componentwas designed and i m p le mented for real 2ti m e app licati ons .Si m ulati on results in T OSSI M demonstrate that the s oft real 2ti m e component i m p r oves the real 2ti m e perfor mance of Tiny OS . Key words:wireless sens or net w orks;Tiny OS;real 2ti m e;component design;T OSSI M 0 引言 无线传感器网络(W ireless Sens or Net w orks,W S N )是由大量体积较小、能源受限,具有一定计算、存储和无线通信能力的传感器节点组成的无结构网络[1,2]。它综合了传感器、嵌入式、无线网络、分布式信息处理等技术。由于W S N 自身具备的特征,已广泛应用于国防军事、环境监测、交通管理、医疗卫生等领域。无线传感器网络作为一个新兴的研究领域,其中存在大量挑战性的研究课题,节点上的操作系统(W ireless Sens or Net w orks Operati on Syste m,W S NOS )设计与实现就是其 中之一。 目前,国外许多大学、研究机构着手于W S NOS 的研究,开发出了Tiny OS [3]、Magnet 、MANTI S 、Sen OS 等具有典型特征的W S NOS 。其中,由UC Berkeley 依靠S martdust (智能尘埃)项目开发出的Tiny OS 得到了广泛关注和应用。 Tiny OS 是全新面向W S N 的源码级构件化操作系统,由 构件开发语言nes C [4]开发,其内核只需要400字节的内存空间即可运行起来,是一个轻量级操作系统。但在实时应用中, Tiny OS 简单的F I F O 调度算法就显得不再适用,在任务数较 多时重要任务的响应时间无法得到保证。因此,针对实时应用的实时性需求,本文深入分析了Tiny OS 22.x 调度机制和调度相关的构件,提出了具有软实时性能的任务调度机制,开发 了相应的系统调度构件,通过在T OSSI M [5]仿真器中进行仿 真分析,此实时系统调度构件能提高Tiny OS 的实时性能。 1 Tiny OS 22.x 的调度机制 1.1 Tiny OS 的任务事件驱动的并发模型 Tiny OS 采用任务和事件驱动[6] 相结合的两级并发模型 (如图1) 。 图1 Tiny OS 任务事件驱动并发模型示意图 任务机制 任务由用户应用程序定义,可以由应用程序或事件处理程序创建。任务由task 关键字定义,具体定义语 法为:task void myTask (){…}。任务由post 关键字创建,具体语法为:post myTask ()。创建任务时,Tiny OS 的调度器将任务加入任务队列的队尾。核心调度策略中的任务调度器把此任务加入任务队列后就立即返回,任务则延迟执行。在等待执行的任务队列中,各个任务之间采用F I F O 原则进行调 第27卷第11期 2007年11月   计算机应用 Computer App licati ons   Vol .27No .11 Nov .2007

探究linux内核,超详细解析子系统

探究linux内核,超详细解析子系统 Perface 前面已经写过一篇《嵌入式linux内核的五个子系统》,概括性比较强,也比较简略,现在对其进行补充说明。 仅留此笔记,待日后查看及补充!Linux内核的子系统 内核是操作系统的核心。Linux内核提供很多基本功能,如虚拟内存、多任务、共享库、需求加载、共享写时拷贝(Copy-On-Write)以及网络功能等。增加各种不同功能导致内核代码不断增加。 Linux内核把不同功能分成不同的子系统的方法,通过一种整体的结构把各种功能集合在一起,提高了工作效率。同时还提供动态加载模块的方式,为动态修改内核功能提供了灵活性。系统调用接口用户程序通过软件中断后,调用系统内核提供的功能,这个在用户空间和内核提供的服务之间的接口称为系统调用。系统调用是Linux内核提供的,用户空间无法直接使用系统调用。在用户进程使用系统调用必须跨越应用程序和内核的界限。Linux内核向用户提供了统一的系统调用接口,但是在不同处理器上系统调用的方法

各不相同。Linux内核提供了大量的系统调用,现在从系统 调用的基本原理出发探究Linux系统调用的方法。这是在一个用户进程中通过GNU C库进行的系统调用示意图,系 统调用通过同一个入口点传入内核。以i386体系结构为例,约定使用EAX寄存器标记系统调用。 当加载了系统C库调用的索引和参数时,就会调用0x80软件中断,它将执行system_call函数,这个函数按照EAX 寄存器内容的标示处理所有的系统调用。经过几个单元测试,会使用EAX寄存器的内容的索引查system_call_table表得到系统调用的入口,然后执行系统调用。从系统调用返回后,最终执行system_exit,并调用resume_userspace函数返回用户空间。 linux内核系统调用的核心是系统多路分解表。最终通过EAX寄存器的系统调用标识和索引值从对应的系统调用表 中查出对应系统调用的入口地址,然后执行系统调用。 linux系统调用并不单层的调用关系,有的系统调用会由

【IT专家】linux多线程及信号处理

本文由我司收集整编,推荐下载,如有疑问,请与我司联系 linux多线程及信号处理 linux多线程及信号处理Linux 多线程应用中如何编写安全的信号处理函数hi.baidu/yelangdefendou/blog/item/827984efd3af7cd9b21cb1df.html Signal Handling Use reentrant functions for safer signal handling linux信号种类1、可靠信号和不可靠信号“不可靠信号” Linux信号机制基本上是从Unix系统中继承过来的。早期Unix系统中的信号机制比较简单和原始,后来在实践中暴露出一些问题,因此,把那些建立在早期机制上的信号叫做”不可靠信号”,信号值小于SIGRTMIN(Red hat 7.2中,SIGRTMIN=32,SIGRTMAX=63)的信号都是不可靠信号。这就是”不可靠信号”的来源。他的主要问题是:? 进程每次处理信号后,就将对信号的响应配置为默认动作。在某些情况下,将导致对信号的错误处理;因此,用户假如不希望这样的操作,那么就要在信号处理函数结尾再一次调用signal(),重新安装该信号。? 信号可能丢失,后面将对此周详阐述。因此,早期unix下的不可靠信号主要指的是进程可能对信号做出错误的反应连同信号可能丢失。Linux支持不可靠信号,但是对不可靠信号机制做了改进:在调用完信号处理函数后,不必重新调用该信号的安装函数(信号安装函数是在可靠机制上的实现)。因此,Linux下的不可靠信号问题主要指的是信号可能丢失。“可靠信号” 随着时间的发展,实践证实了有必要对信号的原始机制加以改进和扩充。因此,后来出现的各种Unix版本分别在这方面进行了研究,力图实现”可靠信号”。由于原来定义的信号已有许多应用,不好再做改变,最终只好又新增加了一些信号,并在一开始就把他们定义为可靠信号,这些信号支持排队,不会丢失。同时,信号的发送和安装也出现了新版本:信号发送函数sigqueue()及信号安装函数sigaction()。POSIX.4对可靠信号机制做了标准化。但是,POSIX只对可靠信号机制应具备的功能连同信号机制的对外接口做了标准化,对信号机制的实现没有作具体的规定。信号值位于SIGRTMIN和SIGRTMAX之间的信号都是可靠信号,可靠信号克服了信号可能丢失的问题。Linux在支持新版本的信号安装函数sigation()连同信号发送函数sigqueue()的同时,仍然支持早期的signal()信号安装函数,支持信号发送函数kill()。注:不

tinyos任务调度机制

TOSH_sched_init();for(;;){TOSH_run_task();} 这两个函数的实现在tinyos-1.x\tos\system目录下的sched.c源文件中。这个文件就实现了tinyos 1.x的调度策略,很简单吧?闲话少说,下面分析它的数据结构。 typedef struct { void (*tp) (); } TOSH_sched_entry_T; 这个结构体就是tinyos任务队列里的东东,里面是个函数指针。 enum { #ifdef TOSH_MAX_TASKS_LOG2 #if TOSH_MAX_TASKS_LOG2 > 8 #error "Maximum of 256 tasks, TOSH_MAX_TASKS_LOG2 must be <= 8" #endif TOSH_MAX_TASKS = 1 << TOSH_MAX_TASKS_LOG2, #else TOSH_MAX_TASKS = 8, #endif TOSH_TASK_BITMASK = (TOSH_MAX_TASKS - 1) }; 上面定义了tinyos任务队列里的最大任务数TOSH_MAX_TASKS,和一个掩码。 //定义tinyos任务队列,这个队列是个循环队列! volatile TOSH_sched_entry_T TOSH_queue[TOSH_MAX_TASKS]; //“头指针”tinyos任务队列里的第一个不为空的任务的下标 uint8_t TOSH_sched_full; //“尾指针”如果tinyos任务队列没有满,则是最后一个不为空的任务 //的下一个元素的下标;如果任务队列满则是最后一个任务的下标。 volatile uint8_t TOSH_sched_free; 好了,数据结构分析完了,咱们看看tinyos是怎样实现这个队列的吧,实现一个队列,无非就是初始化,增加队列元素,删除队列元素,判断队列是否为空……,数据结构里最基本的东东,想必大家比我清楚了!(如果这个不清楚,赶紧回去看看数据结构 ^_^ )。 一初始化 s 初始化函数很简单,大家肯定都会写了。 void TOSH_sched_init(void) { int i; TOSH_sched_free = 0; TOSH_sched_full = 0; for (i = 0; i < TOSH_MAX_TASKS; i++) TOSH_queue[i].tp = NULL;

linux内核IMQ源码实现分析

本文档的Copyleft归wwwlkk所有,使用GPL发布,可以自由拷贝、转载,转载时请保持文档的完整性,严禁用于任何商业用途。 E-mail: wwwlkk@https://www.360docs.net/doc/cf5503400.html, 来源: https://www.360docs.net/doc/cf5503400.html,/?business&aid=6&un=wwwlkk#7 linux2.6.35内核IMQ源码实现分析 (1)数据包截留并重新注入协议栈技术 (1) (2)及时处理数据包技术 (2) (3)IMQ设备数据包重新注入协议栈流程 (4) (4)IMQ截留数据包流程 (4) (5)IMQ在软中断中及时将数据包重新注入协议栈 (7) (6)结束语 (9) 前言:IMQ用于入口流量整形和全局的流量控制,IMQ的配置是很简单的,但很少人分析过IMQ的内核实现,网络上也没有IMQ的源码分析文档,为了搞清楚IMQ的性能,稳定性,以及借鉴IMQ的技术,本文分析了IMQ的内核实现机制。 首先揭示IMQ的核心技术: 1.如何从协议栈中截留数据包,并能把数据包重新注入协议栈。 2.如何做到及时的将数据包重新注入协议栈。 实际上linux的标准内核已经解决了以上2个技术难点,第1个技术可以在NF_QUEUE机制中看到,第二个技术可以在发包软中断中看到。下面先介绍这2个技术。 (1)数据包截留并重新注入协议栈技术

(2)及时处理数据包技术 QoS有个技术难点:将数据包入队,然后发送队列中合适的数据包,那么如何做到队列中的数

激活状态的队列是否能保证队列中的数据包被及时的发送吗?接下来看一下,激活状态的队列的 证了数据包会被及时的发送。 这是linux内核发送软中断的机制,IMQ就是利用了这个机制,不同点在于:正常的发送队列是将数据包发送给网卡驱动,而IMQ队列是将数据包发送给okfn函数。

linux signal()函数

当服务器close一个连接时,若client端接着发数据。根据TCP协议的规定,会收到一个RST响应,client再往这个服务器发送数据时,系统会发出一个SIGPIPE信号给进程,告诉进程这个连接已经断开了,不要再写了。根据信号的默认处理规则SIGPIPE信号的默认执行动作是terminate(终止、退出), 所以client会退出。 若不想客户端退出可以把SIGPIPE设为SIG_IGN 如: signal(SIGPIPE,SIG_IGN); 这时SIGPIPE交给了系统处理。 服务器采用了fork的话,要收集垃圾进程,防止僵死进程的产生,可以这样处理: signal(SIGCHLD,SIG_IGN);交给系统init去回收。 这里子进程就不会产生僵死进程了。 signal(SIGHUP, SIG_IGN); signal信号函数,第一个参数表示需要处理的信号值(SIGHUP),第二个参数为处理函数或者是一个表示,这里,SIG_IGN表示忽略SIGHUP那个注册的信号。 SIGHUP和控制台操作有关,当控制台被关闭时系统会向拥有控制台sessionID的所有进程发送HUP信号,默认HUP信号的action是exit,如果远程登陆启动某个服务进程并在程序运行时关闭连接的话会导致服务进程退出,所以一般服务进程都会用nohup工具启动或写成一个daemon。 unix中进程组织结构为session 包含一个前台进程组及一个或多个后台进程组,一个进程组包含多个进程。 一个session可能会有一个session首进程,而一个session首进程可能会有一个控制终端。 一个进程组可能会有一个进程组首进程。进程组首进程的进程ID与该进程组ID相等。 这儿是可能会有,在一定情况之下是没有的。 与终端交互的进程是前台进程,否则便是后台进程 SIGHUP会在以下3种情况下被发送给相应的进程: 1、终端关闭时,该信号被发送到session首进程以及作为job提交的进程(即用&符号提交的进程)

项目销售团队激励机制与提成方案设计

实用标准文档 长沙融科东塘项目 销售组织及日常管理方案 凌峻(中国)房地产策划代理机构 二OO五年十一月

前言 长沙融科东塘项目作为2006年长沙市最值得期待的楼盘,所针对的目标客户群体是中高端的消费者,目标客户对楼盘的各个方面期望值都较高;为配合项目首期的营销推广工作,销售服务就必须就其他项目有本质的飞跃和提高。本方案就是为解决项目销售准备工作而展开。 “尊重、完美、严谨、专业”的风格是最能体现项目形象及消费群体自尊、自律的心理特点,现场所有工作人员的行为礼节都应体现这一风格,同时使视觉体系与服务体系达到顾客满意的效果!

一、销售部人事组织管理 1、配置原则 针对目标消费群体的特点,按高标准、高起点的要求,充分体现项目的形象定位,除开发商与策划公司组成营销核心外,还需把建筑商、设计院、物业管理公司都对整合到项目的营销战略体台系当中。 2、销售人员的配置 销售部销售中心现场经理一名; 销售主任(组长)2名; 销售代表8名。 3、现场销售人员岗位职责 ●销售代表 认真贯彻执行公司销售管理规定和实施细则,努力提高业务水平; 积极完成制定的销售目标,为客户提供主动、热情、满意及周到的服务; 与客户签订销售合同,督促合同正常如期履行,并积极催讨应收销售款项; 妥善解决在销售过程中出现的问题; 与管理处保持良好的沟通工作,协助客户作好收楼工作; 主动收集市场信息及客户意见,填写每日客户来访登记表、总结每周工作,认真填写销售总结报告; 按照公司的标准合同签约,严守公司商业机密,做到以公司利益为重并遵守公司的各项规章制度及国家的法律法规; 努力达到公司考核要求标准,认真圆满完成公司赋予的各项工作。 ●销售主任(组长) 监督本组销售代表的行为规范; 负责本组的销售工作及收集周边楼盘市场动态; 检查、汇总本组客户来访登记表; 努力提高本组的销售成绩;

Linux中直接IO机制的介绍

Linux 中直接 I/O 机制的介绍https://www.360docs.net/doc/cf5503400.html,/developerworks/cn/linux/l-cn-...

https://www.360docs.net/doc/cf5503400.html,/developerworks/cn/linux/l-cn-...

当应用程序需要直接访问文件而不经过操作系统页高速缓冲存储器的时候,它打开文件的时候需要指定 O_DIRECT 标识符。 操作系统内核中处理 open() 系统调用的内核函数是 sys_open(),sys_open() 会调用 do_sys_open() 去处理主要的打开操作。它主要做了三件事情:首先,它调用 getname() 从进程地址空间中读取文件的路径名;接着,do_sys_open() 调用 get_unused_fd() 从进程的文件表中找到一个空闲的文件表指针,相应的新文件描述符就存放在本地变量 fd 中;之后,函数 do_?lp_open() 会根据传入的参数去执行相应的打开操作。清单 1 列出了操作系统内核中处理 open() 系统调用的一个主要函数关系图。 清单 1. 主要调用函数关系图 sys_open() |-----do_sys_open() |---------getname() |---------get_unused_fd() |---------do_filp_open() |--------nameidata_to_filp() |----------__dentry_open() 函数 do_?ip_open() 在执行的过程中会调用函数 nameidata_to_?lp(),而 nameidata_to_?lp() 最终会调用 __dentry_open()函数,若进程指定了 O_DIRECT 标识符,则该函数会检查直接 I./O 操作是否可以作用于该文件。清单 2 列出了 __dentry_open()函数中与直接 I/O 操作相关的代码。 清单 2. 函数 dentry_open() 中与直接 I/O 相关的代码 if (f->f_flags & O_DIRECT) { if (!f->f_mapping->a_ops || ((!f->f_mapping->a_ops->direct_IO) && (!f->f_mapping->a_ops->get_xip_page))) { fput(f); f = ERR_PTR(-EINVAL); } } 当文件打开时指定了 O_DIRECT 标识符,那么操作系统就会知道接下来对文件的读或者写操作都是要使用直接 I/O 方式的。 下边我们来看一下当进程通过 read() 系统调用读取一个已经设置了 O_DIRECT 标识符的文件的时候,系统都做了哪些处理。函数read() 的原型如下所示: ssize_t read(int feledes, void *buff, size_t nbytes) ; 操作系统中处理 read() 函数的入口函数是 sys_read(),其主要的调用函数关系图如下清单 3 所示: 清单 3. 主调用函数关系图 sys_read() |-----vfs_read() |----generic_file_read() |----generic_file_aio_read() |--------- generic_file_direct_IO()

Quartz任务调度--详细教程

Quartz任务调度快速入门1 概述 各种企业应用几乎都会碰到任务调度的需求,就拿论坛来说:每隔半个小时生成精华文章的RSS文件,每天凌晨统计论坛用户的积分排名,每隔30分钟执行锁定用户解锁任务。 对于一个典型的MIS系统来说,在每月1号凌晨统计上个月各部门的业务数据生成月报表,每半个小时查询用户是否已经有快到期的待处理业务……,这样的例子俯拾皆是,不胜枚举。 任务调度本身涉及到多线程并发、运行时间规则制定和解析、场景保持与恢复、线程池维护等诸多方面的工作。如果直接使用自定义线程这种刀耕火种的原始办法,开发任务调度程序是一项颇具挑战性的工作。Java开源的好处就是:领域问题都能找到现成的解决方案。 OpenSymphony所提供的Quartz自2001年发布版本以来已经被众多项目作为任务调度的解决方案,Quartz在提供巨大灵活性的同时并未牺牲其简单性,它所提供的强大功能使你可以应付绝大多数的调度需求。 Quartz 在开源任务调度框架中的翘首,它提供了强大任务调度机制,难能可贵的是它同时保持了使用的简单性。Quartz 允许开发人员灵活地定义触发器的调度时间表,并可以对触发器和任务进行关联映射。 此外,Quartz提供了调度运行环境的持久化机制,可以保存并恢复调度现场,即使系统因故障关闭,任务调度现场数据并不会丢失。此外,Quartz还提供了组件式的侦听器、各种插件、线程池等功能。 了解Quartz体系结构 Quartz对任务调度的领域问题进行了高度的抽象,提出了调度器、任务和触发器这3个核心的概念,并在org.quartz通过接口和类对重要的这些核心概念进行描述: ●Job:是一个接口,只有一个方法void execute(JobExecutionContext context),开发者实现该接口定义运行任务,JobExecutionContext类提供了调度上下文的各种信息。Job运行时的信息保存在 JobDataMap实例中; ●JobDetail:Quartz在每次执行Job时,都重新创建一个Job实例,所以它不直接接受一个Job的实例,相反它接收一个Job实现类,以便运行时通过newInstance()的反射机制实例化Job。因此需要通过一个类来描述Job的实现类及其它相关的静态信息,如Job名字、描述、关联监听器等信息,JobDetail 承担了这一角色。

Linux内核结构详解教程

Linux内核结构详解教程 ─────Linux内核教程 linux内核就像人的心脏,灵魂,指挥中心。 内核是一个操作系统的核心,它负责管理系统的进程,内存,设备驱动程序,文件和网络系统,决定着系统的性能和稳定性。内核以独占的方式执行最底层任务,保证系统正常运行。协调多个并发进程,管理进程使用的内存,使它们相互之间不产生冲突,满足进程访问磁盘的请求等等. 严格说Linux并不能称做一个完整的操作系统.我们安装时通常所说的Linux,是有很多集合组成的.应称为GNU/Linux. 一个Linux内核很少1.2M左右,一张软盘就能放下. 内容基础,语言简短简洁 红联Linux论坛是致力于Linux技术讨论的站点,目前网站收录的文章及教程基本能满足不同水平的朋友学习。 红联Linux门户: https://www.360docs.net/doc/cf5503400.html, 红联Linux论坛: https://www.360docs.net/doc/cf5503400.html,/bbs 红联Linux 论坛大全,所有致力点都体现在这 https://www.360docs.net/doc/cf5503400.html,/bbs/rf/linux/07.htm

目录 Linux内核结构详解 Linux内核主要五个子系统详解 各个子系统之间的依赖关系 系统数据结构 Linux的具体结构 Linux内核源代码 Linux 内核源代码的结构 从何处开始阅读源代码 海量Linux技术文章

Linux内核结构详解 发布时间:2006-11-16 19:05:29 Linux内核主要由五个子系统组成:进程调度,内存管理,虚拟文件系统,网络接口,进程间通信。

Linux内核主要五个子系统详解 发布时间:2006-11-16 19:05:54 1.进程调度(SCHED):控制进程对CPU的访问。当需要选择下一个进程运行时,由调度程序选择最值得运行的进程。可运行进程实际上是仅等待CPU资源的进程,如果某个进程在等待其它资源,则该进程是不可运行进程。Linux使用了比较简单的基于优先级的进程调度算法选择新的进程。 2.内存管理(MM)允许多个进程安全的共享主内存区域。Linux的内存管理支持虚拟内存,即在计算机中运行的程序,其代码,数据,堆栈的总量可以超过实际内存的大小,操作系统只是把当前使用的程序块保留在内存中,其余的程序块则保留在磁盘中。必要时,操作系统负责在磁盘和内存间交换程序块。内存管理从逻辑上分为硬件无关部分和硬件有关部分。硬件无关部分提供了进程的映射和逻辑内存的对换;硬件相关的部分为内存管理硬件提供了虚拟接口。 3.虚拟文件系统(VirtualFileSystem,VFS)隐藏了各种硬件的具体细节,为所有的设备提供了统一的接口,VFS提供了多达数十种不同的文件系统。虚拟文件系统可以分为逻辑文件系统和设备驱动程序。逻辑文件系统指Linux所支持的文件系统,如ext2,fat等,设备驱动程序指为每一种硬件控制器所编写的设备驱动程序模块。 4.网络接口(NET)提供了对各种网络标准的存取和各种网络硬件的支持。网络接口可分为网络协议和网络驱动程序。网络协议部分负责实现每一种可能的网络传输协议。网络设备驱动程序负责与硬件设备通讯,每一种可能的硬件设备都有相应的设备驱动程序。 5.进程间通讯(IPC) 支持进程间各种通信机制。 处于中心位置的进程调度,所有其它的子系统都依赖它,因为每个子系统都需要挂起或恢复进程。一般情况下,当一个进程等待硬件操作完成时,它被挂起;当操作真正完成时,进程被恢复执行。例如,当一个进程通过网络发送一条消息时,网络接口需要挂起发送进程,直到硬件成功地完成消息的发送,当消息被成功的发送出去以后,网络接口给进程返回一个代码,表示操作的成功或失败。其他子系统以相似的理由依赖于进程调度。

实验四 Linux进程互斥

实验四 Linux进程互斥 一、实验目的 熟悉Linux下信号量机制,能够使用信号量实现在并发进程间的互斥和同步。 二、实验题目 使用共享存储区机制,使多个并发进程分别模拟生产者-消费者模式同步关系、临界资源的互斥访问关系,使用信号量机制实现相应的同步和互斥。 三、背景材料 (一)需要用到的系统调用 实验可能需要用到的主要系统调用和库函数在下面列出,详细的使用方法说明通过“man 2 系统调用名”或者“man 3 函数名”命令获取。 fork() 创建一个子进程,通过返回值区分是在父进程还是子进程中执行; wait() 等待子进程执行完成; shmget() 建立一个共享存储区; shmctl() 操纵一个共享存储区; s hmat() 把一个共享存储区附接到进程内存空间; shmdt() 把一个已经附接的共享存储区从进程内存空间断开; semget() 建立一个信号量集; semctl() 操纵一个信号量集,包括赋初值; semop() 对信号量集进行wait和signal操作; signal() 设置对信号的处理方式或处理过程。 (二)模拟生产者-消费者的示例程序 本示例主要体现进程间的直接制约关系,由于使用共享存储区,也存在间接制约关系。进程分为服务进程和客户进程,服务进程只有一个,作为消费者,在每次客户进程改变共享存储区内容时显示其数值。各客户进程作为生产者,如果共享存储区内容已经显示(被消费),可以接收用户从键盘输入的整数,放在共享存储区。 编译后执行,第一个进程实例将作为服务进程,提示: ACT CONSUMER!!! To end, try Ctrl+C or use kill. 服务进程一直循环执行,直到用户按Ctrl+C终止执行,或使用kill命令杀死服务进程。 其他进程实例作为客户进程,提示: Act as producer. To end, input 0 when prompted. 客户进程一直循环执行,直到用户输入0。 示例程序代码如下: #include #include #include #include #include #include #include #include

任务调度机制

ucos:uc/os 任务调度机制 疯狂代码 https://www.360docs.net/doc/cf5503400.html,/ ?: http:/https://www.360docs.net/doc/cf5503400.html,/NetworkProgramming/Article33556.html uc/os 任务调度机制 by zhang9733 from https://www.360docs.net/doc/cf5503400.html,/gd/dzbbs/ 内核核心任务是任务调度机制为了对uc/os进行分析我们从任务调度开始在uc/os中个任务通常是个无限循环具有如下结构后面我将解释为什么会有这种结构从下面结构可以看出个任务就像其他c样;而且既然任务是个无限循环我们可以想象到它定不会返回任何数据所以返回类型应该定义为void : ------------------------------------------------------------ void mytask(void *pdata) { for (;;) { do something; waiting; do something; } } uc/os可以管理64个任务但目前版本系统占用了两个任务还保留了其他六个任务故用户可以使用56个任务每个任务必须赋予定优先级优先级数越高优先级越低所以0级优先级任务有最高优先级通过在os_cfg.h文件中定义宏os_lowest_prio可以决定系统任务个数系统目前占用两个任务为空闲任务idle task和统计任务stat task当没有其他任务进入就绪状态时空闲任务投入运行空闲任务什么也不做只是简单将计数器加1这个计数器可以用来统计cpu利用率 uc/os下每个任务可以有如下五种状态 休眠态(dormant):指任务驻留在空间中还没有交给内核管理把任务交给内核是通过ostaskcreate( )或ostaskcreatext( )实现 就绪(ready):当任务旦建立这个任务就处于就绪态准备运行任务可以动态被另个建立也可以在系统运行开始之前建立通过ostaskdel( )使任务返回到休眠态就绪态任务都放在就绪列表中在任务调度时指针ostcbhighrdy指向优先级最高就绪任务也就是立刻就要运行任务 运行(running):准备就绪最高优先级任务获得cpu控制权从而处于运行态指针ostcbcur指向正在运行任务

浅谈团队中的激励机制

浅谈团队中的激励机制 摘要:在以人为本的管理理念下,激励管理机制可以极大限度的激发员工实现自我价值的热情,激励他们向教育目标靠近。在激励机制中充分利用心理效应的积极作用,合理规避心理效应的消极作用,让激励管理机制作用充分发挥。研究了工作团队的激励机制,特别分析了工作团队中的薪酬制度,机会主义倾向和解决的办法,一些过程评价方法及层次分析法在工作团队绩效测评中的应用。 关键词:激励管理机制、自我价值、手段、应用

Abstract: In a people-oriented management philosophy, the incentive management system can greatly stimulate the limits of the enthusiasm of staff to achieve self-worth and encourage them to close the aims of education. Make full use of the incentive mechanism the positive role of the psychological effects, reasonable to avoid the negative effects of the psychological effects, so that the role of incentive management system into full play. Study team incentives, in particular the analysis of work teams in the pay system, opportunistic tendencies and a solution, a number of process evaluation methods and analytic hierarchy process in the work team performance measurement application。 Keywords: Incentive management system、Self-worth、Means、Apply

linux通讯

线程+定时实现linux下的Qt串口编程 2010-06-26 10:49 转: 线程+定时实现linux下的Qt串口编程 作者:lizzy115 时间:2010,5,14 说明:本设计采用的是线程+定时实现linux下的Qt串口编程,而非网上资料非常多的Qt编写串口通信程序全程图文讲解系列,因为Qt编写串口通信程序全程图文讲解系列是很好实现,那只是在windows下面的,可是在linux 下面实现串口的通信并非如此,原因在于QextSerialBase::EventDriven跟QextSerialBase::Polling这两个事件的区别,EventDriven属于异步,Polling 属于同步,在windows下面使用的是EventDriven很容易实现,只要有数据就会触发一个串口事件,网上说linux下面需要的是Polling,可是还是不行的,只要串口有数据的时候他会在QByteArray temp = myCom->readAll(); 这句一直读取数据,没能退出,直到断掉串口的时候才能把接受到的串口数据通过 ui->textBrowser->insertPlainText(temp);打印在界面上,一直没能解决这个问题,所以只好采用线程+定时实现linux下的Qt串口编程进行设计。 一、安装环境: 系统平台:Ubuntu-8.04,内核2.6.24-27-generic,图形界面 二、软件需求及下地地址: Qt版本 qt-linux-SDK-4.6.2 注意:此处使用的是qt-linux-SDK-4.6.2版本,编译通过了,之后需要把他移植到qt-embedded-linux-opensource-src-4.5.3.tar.gz,通过qte编译后移植到开发板中,采用的测试开发板为Micro2440, 下载地址:略 三、程序编写过程 程序编程流程: 先新建一个工程空白工程,再建立Ui文件,通过designer进行Ui 界面设计,设计完保存,编译生成ui_mainwindow.h头文件,编写线程头文件及线程处理.cpp文件,建立串口处理头文件及 .cpp文件,最后完成main.cpp 文件。

Linux内核分析-网络[五]:网桥

看完了路由表,重新回到netif_receive_skb ()函数,在提交给上层协议处理前,会执行下面一句,这就是网桥的相关操作,也是这篇要讲解的容。 view plaincopy to clipboardprint? 1. s kb = handle_bridge(skb, &pt_prev, &ret, orig_dev); 网桥可以简单理解为交换机,以下图为例,一台linux机器可以看作网桥和路由的结合,网桥将物理上的两个局域网LAN1、LAN2当作一个局域网处理,路由连接了两个子网1.0和2.0。从eth0和eth1网卡收到的报文在Bridge模块中会被处理成是由Bridge收到的,因此Bridge也相当于一个虚拟网卡。 STP五种状态 DISABLED BLOCKING LISTENING LEARNING FORWARDING 创建新的网桥br_add_bridge [net\bridge\br_if.c] 当使用SIOCBRADDBR调用ioctl时,会创建新的网桥br_add_bridge。 首先是创建新的网桥: view plaincopy to clipboardprint?

1. d ev = new_bridge_dev(net, name); 然后设置dev->dev.type为br_type,而br_type是个全局变量,只初始化了一个名字变量 view plaincopy to clipboardprint? 1. S ET_NETDEV_DEVTYPE(dev, &br_type); 2. s tatic struct device_type br_type = { 3. .name = "bridge", 4. }; 然后注册新创建的设备dev,网桥就相当一个虚拟网卡设备,注册过的设备用ifconfig 就可查看到: view plaincopy to clipboardprint? 1. r et = register_netdevice(dev); 最后在sysfs文件系统中也创建相应项,便于查看和管理: view plaincopy to clipboardprint? 1. r et = br_sysfs_addbr(dev); 将端口加入网桥br_add_if() [net\bridge\br_if.c] 当使用SIOCBRADDIF调用ioctl时,会向网卡加入新的端口br_add_if。 创建新的net_bridge_port p,会从br->port_list中分配一个未用的port_no,p->br会指向br,p->state设为BR_STATE_DISABLED。这里的p实际代表的就是网卡设备。 view plaincopy to clipboardprint? 1. p = new_nbp(br, dev); 将新创建的p加入CAM表中,CAM表是用来记录mac地址与物理端口的对应关系;而刚刚创建了p,因此也要加入CAM表中,并且该表项应是local的[关系如下图],可以看到,CAM表在实现中作为net_bridge的hash表,以addr作为hash值,链入 net_bridge_fdb_entry,再由它的dst指向net_bridge_port。

相关文档
最新文档