新聞中心
隨著計算機技術(shù)的不斷發(fā)展,現(xiàn)代操作系統(tǒng)的軟實時性越來越得到重視。Linux作為一種主流的開源操作系統(tǒng),其內(nèi)核設(shè)計的軟實時性能也得到了廣泛認可。其中,hrtimer是一個重要的軟實時性能優(yōu)化工具,能夠?qū)崿F(xiàn)高精度的定時器管理。本文將深入探究Linux中hrtimer的應(yīng)用技巧,為讀者提供關(guān)于hrtimer的基礎(chǔ)知識和常見用法,幫助讀者更好地優(yōu)化軟實時性能。

成都創(chuàng)新互聯(lián)公司主要從事成都網(wǎng)站設(shè)計、成都網(wǎng)站制作、網(wǎng)頁設(shè)計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)敖漢,十年網(wǎng)站建設(shè)經(jīng)驗,價格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):18980820575
什么是hrtimer?
在深入探究hrtimer的應(yīng)用技巧之前,我們需要了解什么是hrtimer。
hrtimer本質(zhì)上是一種定時器,其中“hr”是high-resolution的縮寫,表示高分辨率。與傳統(tǒng)定時器不同的是,hrtimer能夠?qū)崿F(xiàn)高精度的定時,達到微秒級甚至納秒級的時間精度。同時,hrtimer還能夠進行周期性定時,因此它被廣泛應(yīng)用于實時性要求較高的場景。
hrtimer主要應(yīng)用于Linux內(nèi)核中,可以用來進行內(nèi)核線程調(diào)度、延遲計算、網(wǎng)絡(luò)協(xié)議等場景。同時,hrtimer還被廣泛應(yīng)用于Linux下的各種實時操作系統(tǒng)和實時應(yīng)用程序中。
hrtimer的基本使用方法
理解了hrtimer的概念和作用之后,接下來我們將介紹hrtimer的基本使用方法。
hrtimer的使用分為兩個階段:創(chuàng)建hrtimer和注冊hrtimer。
1. 創(chuàng)建hrtimer
hrtimer的創(chuàng)建需要使用hrtimer_init函數(shù),該函數(shù)定義如下:
“`
void hrtimer_init(struct hrtimer *timer, clockid_t which_clock, enum hrtimer_mode mode);
“`
其中,timer是要創(chuàng)建的hrtimer實例,which_clock是時鐘源,mode是定時器的模式。
2. 注冊hrtimer
hrtimer注冊需要使用hrtimer_start或hrtimer_forward函數(shù),這兩個函數(shù)分別用于啟動或重置定時器。它們的定義如下:
“`
int hrtimer_start(struct hrtimer *timer, const ktime_t expires, const enum hrtimer_mode mode);
void hrtimer_forward(struct hrtimer *timer, ktime_t now, const ktime_t interval);
“`
其中,timer是要注冊的hrtimer實例,expires是定時器的到期時間,mode是定時器的模式。
除此之外,hrtimer還有一些常用的屬性和方法,如下:
– hrtimer_cancel:取消定時器注冊
– hrtimer_get_residue:獲取剩余時間
– hrtimer_get_expires:獲取下次到期時間
– hrtimer_restart:重新啟動定時器
hrtimer應(yīng)用技巧
了解了hrtimer的基本使用方法之后,我們來看一些hrtimer的實際應(yīng)用技巧。
1. 定時管理
在實際應(yīng)用中,有許多場景需要進行定時管理,比如延遲計算、周期性任務(wù)等。此時,hrtimer就能夠派上用場。
比如下面的代碼中,我們使用hrtimer啟動一個定時器,當定時器到期時輸出“hello world”。這個例子展示了如何使用hrtimer進行定時管理:
“`
#include
#include
#include
static struct hrtimer hr_timer;
enum hrtimer_restart timer_callback(struct hrtimer *timer)
{
printk(KERN_INFO “Hello world\n”);
hrtimer_forward(timer, ktime_get(), ktime_set(0, 1000000));
return HRTIMER_RESTART;
}
int init_module(void)
{
ktime_t ktime = ktime_set(0, 1000000);
hrtimer_init(&hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
hr_timer.function = &timer_callback;
hrtimer_start(&hr_timer, ktime, HRTIMER_MODE_REL);
return 0;
}
void cleanup_module(void)
{
hrtimer_cancel(&hr_timer);
}
MODULE_LICENSE(“GPL”);
“`
2. 內(nèi)核線程調(diào)度
線程調(diào)度是Linux內(nèi)核的一項重要功能,它能夠讓內(nèi)核按照某種策略動態(tài)地分配CPU時間給各個線程。在實際應(yīng)用中,可以通過hrtimer來實現(xiàn)內(nèi)核線程調(diào)度。
比如下面的代碼中,我們使用hrtimer代替?zhèn)鹘y(tǒng)的定時器來調(diào)度內(nèi)核線程。具體來說,當定時器到期時,會喚醒對應(yīng)的內(nèi)核線程,從而實現(xiàn)線程調(diào)度:
“`
#include
#include
#include
#include
static enum hrtimer_restart timer_callback(struct hrtimer *timer);
struct task_struct *task;
static struct hrtimer hr_timer;
enum hrtimer_restart timer_callback(struct hrtimer *timer)
{
wake_up_process(task);
hrtimer_forward(timer, ktime_get(), ktime_set(0, 1000000));
return HRTIMER_RESTART;
}
int thread_fn(void *data)
{
printk(KERN_INFO “I’m in\n”);
while (!kthread_should_stop()) {
set_current_state(TASK_INTERRUPTIBLE);
schedule();
printk(KERN_INFO “awaken\n”);
}
printk(KERN_INFO “I’m out\n”);
return 0;
}
int init_module(void)
{
ktime_t ktime = ktime_set(1, 0);
hrtimer_init(&hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
hr_timer.function = &timer_callback;
hrtimer_start(&hr_timer, ktime, HRTIMER_MODE_REL);
task = kthread_create(&thread_fn, NULL, “my_thread”);
wake_up_process(task);
return 0;
}
void cleanup_module(void)
{
hrtimer_cancel(&hr_timer);
kthread_stop(task);
}
MODULE_LICENSE(“GPL”);
“`
3. 延遲計算
延遲計算是一種實時性要求較高的場景。利用hrtimer,我們可以實現(xiàn)高精度的延遲計算。比如下面的代碼中,我們使用hrtimer實現(xiàn)一個每隔10ms打印一次時間戳的程序:
“`
#include
#include
#include
#include
static struct hrtimer hr_timer;
static ktime_t kt_period;
enum hrtimer_restart timer_callback(struct hrtimer *timer)
{
ktime_t currtime, remnder;
currtime = ktime_get();
printk(KERN_INFO “%lld.%lld\n”, (long long)currtime.tv_sec, (long long)currtime.tv_nsec);
remnder = ktime_sub(kt_period, ktime_get());
hrtimer_forward_now(timer, remnder);
return HRTIMER_RESTART;
}
int init_module(void)
{
kt_period = ktime_set(0, 10000000); // 10ms
hrtimer_init(&hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
hr_timer.function = &timer_callback;
hrtimer_start(&hr_timer, kt_period, HRTIMER_MODE_REL);
return 0;
}
void cleanup_module(void)
{
hrtimer_cancel(&hr_timer);
}
MODULE_LICENSE(“GPL”);
“`
成都網(wǎng)站建設(shè)公司-創(chuàng)新互聯(lián),建站經(jīng)驗豐富以策略為先導(dǎo)10多年以來專注數(shù)字化網(wǎng)站建設(shè),提供企業(yè)網(wǎng)站建設(shè),高端網(wǎng)站設(shè)計,響應(yīng)式網(wǎng)站制作,設(shè)計師量身打造品牌風格,熱線:028-86922220linux 中斷 下半部 處理時間過長 怎么辦
linux中斷的命令是“ctrl+c”這個就茄漏早是命令搜嘩。建議在使用的時候使用linux后臺管理命令,這樣任務(wù)操作兩不誤,這個就是linux的多任務(wù)操顫雀作。具體命令可以參考linux就該這樣學(xué)一書,希望能夠幫助你
一、中斷處理為什么要下半部?
Linux在中斷處理中間中斷處理分了上半部和下半部,目的就是提高系統(tǒng)的響應(yīng)能力和并發(fā)能力。通俗一點來講:當一個中斷產(chǎn)生,調(diào)用該中斷對應(yīng)的處理程序(上半部)然后告訴系統(tǒng),對應(yīng)的后半部可以執(zhí)行了。然后中斷處理程序就返回,下半部會在合適的時機有系統(tǒng)調(diào)用。這樣一來就大大的減少了中斷處理所需要的時間。
二、那些工作應(yīng)該放在上半部,那些應(yīng)該放在下半部?
沒有嚴格的規(guī)則,只有一些提示:
1、對時間非常敏感,放在上半部。
2、與硬件相關(guān)的,放在上半部。
3、不能被其他中斷打斷的工作,放在上半部。
以上三點之外的,考慮放在下半部。
三、下半部機制在Linux中是怎么實現(xiàn)的?
下半部在Linux中有以下實現(xiàn)機制:
1、BH(在2.5中刪除)
2、任務(wù)隊列(task queue,在2.5刪除)
3、軟中斷(softirq,2.3開始。本文重點)
4、tasklet(2.3開始)
5、工作隊列(work queue,2.5開始)
四、軟中斷是怎么實現(xiàn)的(以下代碼出自2.6.32)?
軟中斷不會搶占另外一個軟中斷,唯一可以搶占軟中斷的是中斷處理程序。
軟中斷可以在不同CPU上并發(fā)執(zhí)行(哪怕是同一個軟中斷)
1、軟中斷是編譯期間靜態(tài)分配的,定義如畝源下:
struct softirq_action { void (*action)(struct softirq_action *); };
/*
* PLEASE, avoid to allocate new softirqs, if you need not _really_ high
* frequency threaded job scheng. For almost all the purposes
* tasklets are more than enough. F.e. all serial device BHs et
* al. should be converted to tasklets, not to softirqs.
*/
enum {
HI_SOFTIRQ=0,
TIMER_SOFTIRQ,
NET_TX_SOFTIRQ,
NET_RX_SOFTIRQ,
BLOCK_SOFTIRQ,
BLOCK_IOPOLL_SOFTIRQ,
TASKLET_SOFTIRQ,
SCHED_SOFTIRQ,
HRTIMER_SOFTIRQ,
RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */
NR_SOFTIRQS
};
/*
* map softirq index to softirq name. update ‘softirq_to_name’ in * kernel/softirq.c when adding a new softirq.
*/
extern char *softirq_to_name;
static struct softirq_action softirq_vec __cacheline_aligned_in_p;
說明:
(1)、軟中斷的個數(shù)書上說是32,看來到這個版本已經(jīng)發(fā)生變化了。
(2)、void (*action)(struct softirq_action *);傳遞整個結(jié)構(gòu)體指針在于當結(jié)構(gòu)體成員發(fā)生變化是,接口不變。
2、系統(tǒng)執(zhí)行軟中斷一個注冊的軟中斷必須被標記后才會執(zhí)行(觸發(fā)軟中斷),通常中斷處理程序會在返回前標記它的軟中斷。在下列地方,待處理的軟中斷會被執(zhí)行:
(1)、從一個硬件迅悉態(tài)中斷代碼處返回。
(2)、在ksoftirqd內(nèi)核線程。
(3)、在那些顯示檢查和執(zhí)行待處理的軟中斷代碼中。
ksoftirqd說明:
每個處理器都有一個這樣的線程。所有線程的名字都叫做ksoftirq/n,區(qū)別在于n,它對應(yīng)的是處理器的編號。在一個雙CPU的機器上就有兩個這樣陸世的線程,分別叫做ksoftirqd/0和ksoftirqd/1。為了保證只要有空閑的處理器,它們就會處理軟中斷,所以給每個處理器都分配一個這樣的線程。
執(zhí)行軟中斷的代碼如下:
alinkage void __do_softirq(void)
{
struct softirq_action *h;
__u32 pending;
int max_restart = MAX_SOFTIRQ_RESTART;
int cpu;
pending = local_softirq_pending();
account_system_vtime(current);
__local_bh_disable((unsigned long)__builtin_return_address(0));
lockdep_softirq_enter();
cpu = p_processor_id();
restart:
/* Reset the pending bitmask before enabling irqs */
set_softirq_pending(0);
local_irq_enable();
h = softirq_vec;
do {
if (pending & 1) {
int prev_count = preempt_count();
kstat_incr_softirqs_this_cpu(h – softirq_vec);
trace_softirq_entry(h, softirq_vec);
h->action(h);
trace_softirq_exit(h, softirq_vec);
if (unlikely(prev_count != preempt_count())) {
printk(KERN_ERR “huh, entered softirq %td %s %p”
“with preempt_count %08x,”
” exited with %08x?\n”, h – softirq_vec,
softirq_to_name,
h->action, prev_count, preempt_count());
preempt_count() = prev_count;
}
rcu_bh_qs(cpu);
}
h++;
pending >>= 1;
} while (pending);
local_irq_disable();
pending = local_softirq_pending();
if (pending && –max_restart)
goto restart;
if (pending)
wakeup_softirqd();
lockdep_softirq_exit();
account_system_vtime(current);
_local_bh_enable();
}
3、編寫自己的軟中斷
(1)、分配索引,在HI_SOFTIRQ與NR_SOFTIRQS中間添加自己的索引號。
(2)、注冊處理程序,處理程序:open_softirq(索引號,處理函數(shù))。
(3)、觸發(fā)你的軟中斷:raise_softirq(索引號)。
4、軟中斷處理程序注意
(1)、軟中斷處理程序執(zhí)行的時候,允許響應(yīng)中斷,但自己不能休眠。
(2)、如果軟中斷在執(zhí)行的時候再次觸發(fā),則別的處理器可以同時執(zhí)行,所以加鎖很關(guān)鍵。
加入等待隊列,等系統(tǒng)有空的時候執(zhí)行
kill -9 強制殺死?。?!
linux hrtimer用法的介紹就聊到這里吧,感謝你花時間閱讀本站內(nèi)容,更多關(guān)于linux hrtimer用法,深入探究:Linux中hrtimer的應(yīng)用技巧,linux 中斷 下半部 處理時間過長 怎么辦的信息別忘了在本站進行查找喔。
成都網(wǎng)站建設(shè)選創(chuàng)新互聯(lián)(?:028-86922220),專業(yè)從事成都網(wǎng)站制作設(shè)計,高端小程序APP定制開發(fā),成都網(wǎng)絡(luò)營銷推廣等一站式服務(wù)。
分享名稱:深入探究:Linux中hrtimer的應(yīng)用技巧(linuxhrtimer用法)
當前網(wǎng)址:http://fisionsoft.com.cn/article/dhhpcsj.html


咨詢
建站咨詢
