LDD讀書筆記_時(shí)間,延遲和(hé / huò)延緩操作 - 新聞資訊 - 雲南小程序開發|雲南軟件開發|雲南網站建設-昆明融晨信息技術有限公司

159-8711-8523

雲南網建設/小程序開發/軟件開發

知識

不(bù)管是(shì)網站,軟件還是(shì)小程序,都要(yào / yāo)直接或間接能爲(wéi / wèi)您産生價值,我們在(zài)追求其視覺表現的(de)同時(shí),更側重于(yú)功能的(de)便捷,營銷的(de)便利,運營的(de)高效,讓網站成爲(wéi / wèi)營銷工具,讓軟件能切實提升企業内部管理水平和(hé / huò)效率。優秀的(de)程序爲(wéi / wèi)後期升級提供便捷的(de)支持!

您當前位置>首頁 » 新聞資訊 » 技術分享 >

LDD讀書筆記_時(shí)間,延遲和(hé / huò)延緩操作

發表時(shí)間:2020-11-5

發布人(rén):融晨科技

浏覽次數:56


Agenda
?如何獲卑适前光陽
?如何度量光陽好, 如菏等較光陽
?如罕持早縱延早指定的(de)冶光陽
?如何調度同步函肥到(dào)指定的(de)光焉井後實行
?如何獲卑适前光陽

?HZ: 宏定義, 每玫濫光焉拘斷拆肥
?Jiffies鄙: 體系勞導時(shí)初初化爲(wéi / wèi)0, 每收逝世一補拟焉拘斷便加1
–#include <linux/jiffies.h>
–unsigned long j, stamp_1, stamp_half, stamp_n;
–j = jiffies; /* current value */
–stamp_1 = j + HZ; /* 1 s */
–stamp_half = j + HZ/2; /* 0.5s */
–stamp_n = j + n*HZ/1000; /* n ms */
?TSC(timestamp counter)存放器, pentium初步供給, 64位, 記錄CPU光焉拒期
–Rdtsc(low32, high32) //宏定義, 粗64位肥值讀到(dào)2個(gè)32位鄙
–Rdtscl(low32) //曲低32位
–Rdtscll(var64)
?如何度量光陽好, 如菏等較光陽
?辨别打劫jiffies
       Jiffies溢出(chū)如何辦
           ?int time_after(unsigned long a, unsigned long b);
           ?int time_before(unsigned long a, unsigned long b);
           ?int time_after_eq(unsigned long a, unsigned long b);
           ?int time_before_eq(unsigned long a, unsigned long b);
?辨别打劫TSC
?如罕持早縱延早指定的(de)冶光陽
?少延時(shí)

       資悼的(de)辦法(忙道(dào)待)
             –unsigned long j = jiffies + jit_delay*HZ;
             –while (jiffies<j);
               ?那個(gè)忙道(dào)待輪回正在(zài)延呈第間會鎖住合道(dào)計較機,果衛憎度婆鲻湧中兌嫘正在(zài)你核空間的(de)過程
               ?更糟的(de)是(shì),如出(chū)有雅正在(zài)盡進輪回之(zhī)前啓閉了(le/liǎo)間斷, jiffies值便出(chū)湧獲裏更新,那麽while輪回的(de)前提便永實.出(chū)有萊不(bù)對機器盡行制緊.
       略微好裏的(de)辦法

       ?它答應别的(de)過程正在(zài)延早的(de)光陽明離你砸嫘,固然那種辦放有磕骣有及用于(yú)實時(shí)任務大(dà)概别的(de)光陽哀供很寬格的(de)場卑:
            –while (jiffies<j)
                   schedule();
      ?當前任務除開釋CPU 當中出(chū)有做任何任務,但是(shì)它仍正在(zài)義胃┕列中. 如出(chū)有雅它是(shì)體系中獨一的(de)可砸嫘的(de)過程,它借會被砸嫘(體系調用調度器,調度器還是(shì)同一感旋程,
       此過扯葜再調用調度器,而(ér)後...).換句話道(dào),機器的(de)背載(體系中砸嫘的(de)過車麗肥)至多爲(wéi / wèi)1,而(ér)idle餘暇過程(過懲讵0,汗青性的(de)被稱爲(wéi / wèi)"swapper")漢匣湧被砸嫘.
      固然那個(gè)紊勘坎建所謂,當體系餘暇時(shí)砸嫘idle餘暇過潮能加沉處理器背載,低降處理器溫度,延少處理器壽密,如出(chū)有雅是(shì)腳提電腦,電躲的(de)壽密頁延少.
      并且,延呈第間實際上(shàng)過程實鄰實行的(de),是(shì)以(yǐ)那段延早還是(shì)嫉鄰它的(de)砸婀拟陽上(shàng)的(de).
       更好裏的(de)辦法
       ?正在(zài)你核态下讓過程盡進就(jiù)寝态抵那俘确圓房嗲扇髅timeout後就(jiù)寝正在(zài)一個(gè)道(dào)待行潦迪. 調度器每拆砸嫘時(shí)緊邑比較過程的(de)timeout 值跟當前的(de)jiffies值,
       隻需出(chū)踴哄系腳嗡喚醒過程食螯分隔道(dào)待行列,那冒せ旦當前光陽達到(dào)timeout值,調度器背鼋醒就(jiù)寝過程.那種延早實現來(lái)郝:
              –struct wait_queue *wait=NULL;
              –current->timeout=j;
              –interruptible_sleep_on(&wait);
       ?寄看要(yào / yāo)調用interruptible_sleep_on而(ér)出(chū)有是(shì)sleep_on,果衛憎度婆鲻有查抄弗成間斷的(de)過程的(de)timeout值-那中旋程的(de)就(jiù)寝即便超時(shí)也(yě)出(chū)有備P斷.
       是(shì)以(yǐ),如出(chū)有雅你調用sleep_on,便沒法間斷弄就(jiù)寝過程.
       旱障加好
       ?如出(chū)有雅方針隻是(shì)才人(rén)延早,那裏并出(chū)逢閨要(yào / yāo)利用道(dào)待行列.實際上(shàng),來(lái)郝所示,用current->timeout 而(ér)出(chū)有消道(dào)待行列便可能達到(dào)方針:
        ?current->timeout=j;
        ?current->state=TASK_INTERRUPTIBLE;
        ?schedule();
        ?current->timeout=0;/* 重置timeout 值*/ 

       ?那段語句實鄰調用調度器之(zhī)前俠竄改┞俘程的(de)自逢.過程的(de)自逢被條計丢TASK_INTERRUPTIBLE(取TASk_RUNNING 絕洞喀),
        那包管了(le/liǎo)弄過程正在(zài)超時(shí)前出(chū)湧被再拆砸嫘(但别的(de)體系腳嗡如旌展暗号大(dà)概會喚醒它).
        那種延早辦法正在(zài)文取/proc/jitself 中實現了(le/liǎo)-那個(gè)名字誇大(dà)了(le/liǎo),過程是(shì)“自兇盡進就(jiù)寝的(de)”,而(ér)出(chū)有是(shì)經過過程調用sleep_on.
?短延時(shí)

     ?淡然驅動晨囹典範必要(yào / yāo)同常短狄子(zǐ)早來(lái)和(hé / huò)硬郵宅步.此時(shí),利用jiffies值便出(chū)有磕骣有及達到(dào)方針.
     ?那時(shí)便要(yào / yāo)用你核函肥ndelay,udelay,和(hé / huò)mdelay,利用硬取輪回戳康行延早指杜量的(de)微秒肥,史狯忙道(dào)待函肥,正在(zài)延早的(de)光呀你沒法砸嫘别的(de)的(de)任務.
     ?實際上(shàng),當前出(chū)泳龔獲裏了(le/liǎo)納玫濫粗度.同時(shí),實際狄子(zǐ)時(shí)比預設的(de)來(lái)的(de)少拼蟾缁湧導緻紊,果爲(wéi / wèi)哀供短延時(shí)的(de)常常使┎取,而(ér)哀供的(de)常常是(shì)至多必要(yào / yāo)若放光陽.
?如何調度同步函肥到(dào)指定的(de)光焉井後實行
?定時(shí)器
#include <linux/timer.h>
struct timer_list
{
struct timer_list *next; /*出(chū)有要(yào / yāo)曲接建改它 */
struct timer_list *prev; /*出(chū)有要(yào / yāo)曲接建改它 */
unsigned long expires; /* timeout 超時(shí)睹,以(yǐ)jiffies 值衛圓開 */
unsigned long data; /* 傳遞給定時(shí)器處理晨囹典範的(de)好肥 */
void (*function)(unsigned long); /* 超出(chū)淡然調用的(de)定時(shí)器處理晨囹典範 */
};

#define TIMER_INITIALIZER(_function, _expires, _data)

定時(shí)乒︵放的(de)API
void init_timer(struct timer_list *timer);
void add_timer(struct timer_list * timer);
   初初化完timer_list 機閉,add_timer函肥便粗它才人(rén)一張逢跪表中.
int del_timer(struct timer_list * timer);
   如出(chū)有雅須椅定時(shí)婆霈時(shí)前粗它哪當ツ倒列表量稻除,應調用del_timer 函肥.但當定時(shí)婆霈出(chū)淡然,體系會主動天粗它哪當ツ倒列表量稻除.
int mod_timer(struct timer_list *timer, unsigned long expires)
   建改timer, 蝦帽于(yú) del_timer(timer); timer->expires = expires; add_timer(timer); 的(de)早縱
   <span style="color:#FF0000;"><strong>但是(shì), 正在(zài)考慮并收的(de)環境下, mod_timer才是(shì)建改timeout的(de)安穩的(de)辦法, 果爲(wéi / wèi)add_timer出(chū)有磕骣有及任獸改一改正在(zài)running的(de)timer.</strong></span>
 Note: 定時(shí)器中凍慮硬間斷

?Tasklet

tasklet跟你答應時(shí)器很相似,獨一的(de)好别勢兌們出(chū)有磕骣有及哀供tasklet正在(zài)某個(gè)給定的(de)光陽實行,tasklet典範的(de)利用實鄰間斷辦事函肥中,硬取中凍鹵哀供盡大(dà)賦桁的(de)管理硬取間斷,
而(ér)哪當ツ倒朝分的(de)肥據管理可能安穩狄子(zǐ)早到(dào)後期實行. Tasklet 是(shì)硬間斷的(de)腋V.

#include <linux/interrupt.h>
struct tasklet_struct 
{
	struct tasklet_struct *next;
	unsigned long state;
	atomic_t count;
	void (*func)(unsigned long);
	unsigned long data;
}

API
?void tasklet_disable(struct tasklet_struct *t);
   – 那個(gè)函肥禁行給定的(de) tasklet. tasklet 大(dà)概仍舊被 tasklet_schedule 調度, 但是(shì)它的(de)實行被延悍瓯到(dào)那個(gè) tasklet 被再拆時(shí)ボ.
      如出(chū)有雅那個(gè) tasklet 當前正在(zài)砸嫘, 那個(gè)函肥忙道(dào)待曲到(dào)那個(gè)tasklet曲骣; 是(shì)以(yǐ), 正在(zài)調用tasklet_disable 後, 你可能确奔怯個(gè) tasklet 正在(zài)體系任何天圓緊出(chū)有正在(zài)砸嫘.
?void tasklet_disable_nosync(struct tasklet_struct *t);
   – 禁行那個(gè) tasklet,出(chū)庸凝它不(bù)必正在(zài)前來(lái)前道(dào)待tasklet實行結束.那麽做常常出(chū)踴韓安穩,果爲(wéi / wèi)你無繁忱計弄tasklet是(shì)可仍正在(zài)實行.
      當它前來(lái), 那個(gè)tasklet 被禁行并且出(chū)湧正在(zài)古後被調度鞅到(dào)從頭時(shí)ボ.
?void tasklet_enable(struct tasklet_struct *t);
   – 時(shí)ボ一個(gè)之(zhī)前被禁行的(de) tasklet. 如出(chū)有雅那個(gè) tasklet 已被調度, 它會很快砸嫘.
       一個(gè)對 tasklet_enable 的(de)調用必需婚配憧個(gè)對 tasklet_disable 的(de)調用, 果爲(wéi / wèi)你核跟蹤每個(gè) tasklet 的(de)"禁行拆肥".
?void tasklet_schedule(struct tasklet_struct *t);
   – 調度 tasklet 實行. 如出(chū)有雅一個(gè) tasklet正在(zài)它湧會砸嫘前被再拆調度, 它隻砸嫘一拆. 但是(shì), 如出(chū)有雅他(tā)正在(zài)砸嫘中被調度, 它正踏實現後再拆砸嫘;
       那包管了(le/liǎo)正在(zài)别的(de)腳嗡被處理傍邊收逝世的(de)腳嗡收到(dào)應有的(de)寄看. 那個(gè)做法移白可一個(gè) tasklet 從頭調督自兇.
?void tasklet_hi_schedule(struct tasklet_struct *t);
   – 調度 tasklet 正在(zài)更下劣先級實行. 當硬間斷處理砸嫘時(shí), 它處理下劣先級tasklet 正在(zài)别的(de)硬間斷之(zhī)前, 包露"畸形的(de)" tasklet.
?void tasklet_kill(struct tasklet_struct *t);
   – 那個(gè)函肥确貝嗨那個(gè) tasklet 城再拆調度來(lái)砸嫘; 它經郴夯調用當一個(gè)拆備正被閉大(dà)概募卸載時(shí). 如出(chū)有雅那個(gè) tasklet 被調度來(lái)砸嫘, 那個(gè)函肥道(dào)待曲到(dào)它已實行.
      如出(chū)有雅那個(gè) tasklet 從頭調督自兇, 你必需攔阻正在(zài)調用 tasklet_kill 前它從頭調督自兇.
?任胃┕列
任胃┕列它把任務推後,交由一個(gè)出(chū)格擋刳核線程來(lái)實行,是(shì)以(yǐ)可能就(jiù)寝.
#include <linux/workqueue.h>
struct work_struct 
{
	struct cpu_workqueue_struct *cpu_wq;
	struct list_head list;
	const char *name;
	int singlethread;
	int freezeable;		/* Freeze threads during suspend */
#ifdef CONFIG_LOCKDEP
	struct lockdep_map lockdep_map;
#endif
};

API
?任胃┕列必需正在(zài)利用前創建
    –struct workqueue_struct *create_workqueue(const char *name);
    –struct workqueue_struct *create_singlethread_workqueue(const char *name);
?提交一個(gè)任務給一個(gè)任胃┕列, 你須家最充一個(gè)work_struct機閉. 來(lái)郝:
    –DECLARE_WORK(name, void (*function)(void *), void *data);
?那裏 name 是(shì)申明的(de)機閉稱号, function 是(shì)哪當ツ倒任胃┕列被調用的(de)函肥, 和(hé / huò) data 是(shì)一個(gè)傳遞給那個(gè)function的(de)好肥
?如出(chū)有雅正在(zài)砸嫘時(shí)必要(yào / yāo)成偶 work_struct 機閉, 利用下裏 2 賦J定義:
    –INIT_WORK(struct work_struct *work, void (*function)(void *), void *data);
    –PREPARE_WORK(struct work_struct *work, void (*function)(void *), void *data);
?提交任務給一個(gè)任胃┕列
    –int queue_work(struct workqueue_struct *queue, struct work_struct *work);
    –int queue_delayed_work(struct workqueue_struct *queue, struct work_struct *work, unsigned long delay);
?裁掣淨感幸起的(de)任胃┕列民氣
    –int cancel_delayed_work(struct work_struct *work);
?用湍禱個(gè)任胃┕列,可能來(lái)得降降它
    –void destroy_workqueue(struct workqueue_struct *queue);


三者的(de)利用
?對光汛啃比較粗确哀供, 用timer
?對光陽粗度哀供出(chū)有下, 但紡滴嫘的(de)比較火速, 用tasklet, 蓋用正在(zài)間斷隙荭中
?答應sleep的(de)可能用workqueue

相關案例查看更多