欧美性猛交xxxx免费看_牛牛在线视频国产免费_天堂草原电视剧在线观看免费_国产粉嫩高清在线观看_国产欧美日本亚洲精品一5区

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux內(nèi)核用戶態(tài)是如何睡眠的

B4Pb_gh_6fde77c ? 來源:Linux內(nèi)核遠航者 ? 作者:Linux內(nèi)核遠航者 ? 2021-08-16 15:06 ? 次閱讀

4.用戶態(tài)睡眠

以sleep為例來說明任務(wù)在用戶態(tài)是如何睡眠的。

首先我們通過strace工具來看下其調(diào)用的系統(tǒng)調(diào)用:

$ strace sleep 1

...

close(3) = 0

clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=1, tv_nsec=0}, NULL) = 0

close(1) = 0

...

可以發(fā)現(xiàn)sleep主要調(diào)用clock_nanosleep系統(tǒng)調(diào)用來進行睡眠(也就是說用戶態(tài)任務(wù)睡眠需要調(diào)用系統(tǒng)調(diào)用陷入內(nèi)核)。

下面我們來研究下clock_nanosleep的實現(xiàn)(這里集中到睡眠的實現(xiàn),先忽略掉定時器等諸多的技術(shù)細節(jié)):

kernel/time/posix-timers.c

SYSCALL_DEFINE4(clock_nanosleep

-》const struct k_clock *kc = clockid_to_kclock(which_clock); //根據(jù)時鐘類型得到內(nèi)核時鐘結(jié)構(gòu)

return kc-》nsleep(which_clock, flags, &t); //調(diào)用內(nèi)核時鐘結(jié)構(gòu)的nsleep回調(diào)

我們傳遞過來的時鐘類型為CLOCK_REALTIME,則調(diào)用鏈為:

kc-》nsleep(CLOCK_REALTIME, flags, &t)

-》clock_realtime.nsleep

-》common_nsleep

-》hrtimer_nanosleep //kernel/time/hrtimer.c

-》hrtimer_init_sleeper_on_stack

-》__hrtimer_init_sleeper

-》__hrtimer_init(&sl-》timer, clock_id, mode); //初始化高精度定時器

sl-》timer.function = hrtimer_wakeup; //設(shè)置超時回調(diào)函數(shù)

sl-》task = current;。//設(shè)置超時時要喚醒的任務(wù)

-》do_nanosleep //睡眠操作

可以看到,睡眠函數(shù)最終調(diào)用到hrtimer_nanosleep,它調(diào)用了兩個主要函數(shù):__hrtimer_init_sleeper和do_nanosleep,前者主要設(shè)置高精度定時器,后者就是真正的睡眠,主要來看下do_nanosleep:

kernel/time/hrtimer.c

do_nanosleep

-》

do {

set_current_state(TASK_INTERRUPTIBLE); //設(shè)置可中斷的睡眠狀態(tài)

hrtimer_sleeper_start_expires(t, mode); //開啟高精度定時器

if (likely(t-》task))

freezable_schedule(); //主動調(diào)度

hrtimer_cancel(&t-》timer);

mode = HRTIMER_MODE_ABS;

} while (t-》task && !signal_pending(current)); //是否記錄的有任務(wù)且沒有掛起的信號

__set_current_state(TASK_RUNNING); //設(shè)置為可運行狀態(tài)

do_nanosleep函數(shù)是睡眠的核心實現(xiàn):首先設(shè)置任務(wù)的狀態(tài)為可中斷的睡眠狀態(tài),然后開啟了之前設(shè)置的高精度定時器,隨即調(diào)用freezable_schedule進行真正的睡眠。

來看下freezable_schedule:

//include/linux/freezer.h

freezable_schedule

-》schedule()

-》__schedule(false);

可以看到最終調(diào)用主調(diào)度器__schedule進行主動調(diào)度。

當(dāng)任務(wù)睡眠完成,定時器超時,會調(diào)用之前在__hrtimer_init_sleeper設(shè)置的超時回調(diào)函數(shù)hrtimer_wakeup將睡眠的任務(wù)喚醒(關(guān)于進程喚醒在這里就不在贅述,在后面的進程喚醒專題文章在進行詳細解讀),然后就可以再次獲得處理器的使用權(quán)了。

總結(jié):處于用戶態(tài)的任務(wù),如果想要睡眠一段時間必須向內(nèi)核請求服務(wù)(如調(diào)用clock_nanosleep系統(tǒng)調(diào)用),內(nèi)核中會設(shè)置一個高精度定時器,來記錄要睡眠的任務(wù),然后設(shè)置任務(wù)狀態(tài)為可中斷的睡眠狀態(tài),緊接著發(fā)生主動調(diào)度,這樣任務(wù)就發(fā)生睡眠了。

5.內(nèi)核態(tài)睡眠

當(dāng)任務(wù)處于內(nèi)核態(tài)時,有時候也需要睡眠一段時間,不像任務(wù)處于用戶態(tài)需要發(fā)生系統(tǒng)調(diào)用來請求內(nèi)核進行睡眠,在內(nèi)核態(tài)可以直接調(diào)用睡眠函數(shù)。當(dāng)然,內(nèi)核態(tài)中,睡眠有兩種場景:一種是睡眠特定的時間的延遲操作(喚醒條件為超時),一種是等待特定條件滿足(如IO讀寫完成,可睡眠的鎖被釋放等)。

下面分別以msleep和mutex鎖為例講解內(nèi)核態(tài)睡眠:

5.1 msleep

msleep做ms級別的睡眠延遲。

//kernel/time/timer.c

void msleep(unsigned int msecs)

{

unsigned long timeout = msecs_to_jiffies(msecs) + 1; //ms時間轉(zhuǎn)換為jiffies

while (timeout)

timeout = schedule_timeout_uninterruptible(timeout); //不可中斷睡眠

}

下面看下schedule_timeout_uninterruptible:

這里涉及到一個重要數(shù)據(jù)結(jié)構(gòu)process_timer

struct process_timer {

struct timer_list timer; //定時器結(jié)構(gòu)

struct task_struct *task; //定時器到期要喚醒的任務(wù)

};

schedule_timeout_uninterruptible

-》 __set_current_state(TASK_UNINTERRUPTIBLE); //設(shè)置任務(wù)狀態(tài)為不可中斷睡眠

return schedule_timeout(timeout);

-》expire = timeout + jiffies; //計算到期時的jiffies值

timer.task = current; //記錄定時器到期要喚醒的任務(wù) 為當(dāng)前任務(wù)

timer_setup_on_stack(&timer.timer, process_timeout, 0); //初始化定時器 超時回調(diào)為process_timeout

__mod_timer(&timer.timer, expire, MOD_TIMER_NOTPENDING); //添加定時器

schedule(); //主動調(diào)度

再看下超時回調(diào)為process_timeout:

process_timeout

-》struct process_timer *timeout = from_timer(timeout, t, timer); //通過定時器結(jié)構(gòu)獲得process_timer

wake_up_process(timeout-》task); //喚醒其管理的任務(wù)

可以看到,msleep實現(xiàn)睡眠也是通過定時器,首先設(shè)置當(dāng)前任務(wù)狀態(tài)為不可中斷睡眠,然后設(shè)置定時器超時時間為傳遞的ms級延遲轉(zhuǎn)換的jiffies,超時回調(diào)為process_timeout,然后將定時器添加到系統(tǒng)中,最后調(diào)用schedule發(fā)起主動調(diào)度,當(dāng)定時器超時的時候調(diào)用process_timeout來喚醒睡眠的任務(wù)。

5.2 mutex鎖

mutex鎖是可睡眠鎖的一種,當(dāng)申請mutex鎖時發(fā)現(xiàn)其他內(nèi)核路徑已經(jīng)持有這把鎖,當(dāng)前任務(wù)就會睡眠等待在這把鎖上。

下面我們來看他的實現(xiàn),主要看睡眠的部分:

kernel/locking/mutex.c

mutex_lock

-》__mutex_lock_slowpath

-》__mutex_lock(lock, TASK_UNINTERRUPTIBLE, 0, NULL, _RET_IP_) //睡眠的狀態(tài)為不可中斷睡眠

-》__mutex_lock_common

-》

...

waiter.task = current; //記錄需要喚醒的任務(wù)為當(dāng)前任務(wù)

set_current_state(state); //設(shè)置睡眠狀態(tài)

for (;;) {

if (__mutex_trylock(lock)) //嘗試獲得鎖

goto acquired;

schedule_preempt_disabled();

-》schedule(); //主動調(diào)度

}

acquired:

__set_current_state(TASK_RUNNING);//設(shè)置狀態(tài)為可運行狀態(tài)

可以看到mutex鎖實現(xiàn)睡眠套路和之前是一樣的:申請mutex鎖的時候,如果其他內(nèi)核路徑已經(jīng)持有這把鎖,首先通過mutex鎖的相關(guān)結(jié)構(gòu)來記錄下當(dāng)前任務(wù),然后設(shè)置任務(wù)狀態(tài)為不可中斷睡眠,接著在一個for循環(huán)中調(diào)用schedule_preempt_disabled發(fā)生主動調(diào)度,于是當(dāng)前任務(wù)就睡眠在這把鎖上。

當(dāng)其他內(nèi)核路徑釋放了這把鎖,就會喚醒等待在這把鎖上的任務(wù),當(dāng)前任務(wù)就獲得了這把鎖,然后進入鎖的臨界區(qū),喚醒操作就完成了(關(guān)于喚醒的技術(shù)細節(jié),后面的喚醒專題會詳細講解)。

6.總結(jié)

進程睡眠按照應(yīng)用場景可以分為:延遲睡眠和等待某些特定條件而睡眠,實際上都可以歸于等待某些特定條件而睡眠,因為延遲特定時間也可以作為特定條件。

進程睡眠按照進程所處的特權(quán)級別可以分為:用戶態(tài)進程睡眠和內(nèi)核態(tài)進程睡眠,用戶態(tài)進程睡眠需要進程通過系統(tǒng)調(diào)用陷入內(nèi)核來發(fā)起睡眠請求。對于進程睡眠,內(nèi)核主要需要做三大步操作:

1.設(shè)置任務(wù)狀態(tài)為睡眠狀態(tài) 2.記錄睡眠的任務(wù) 3.發(fā)起主動調(diào)度。這三大步操作都是非常有必要,第一步設(shè)置睡眠狀態(tài)為后面調(diào)用主調(diào)度器做必要的標(biāo)識準(zhǔn)備;第二步記錄下睡眠的任務(wù)是為了以后喚醒任務(wù)來準(zhǔn)備的;第三步是睡眠的主體部分,這里會將睡眠的任務(wù)從運行隊列中踢出,選擇下一個任務(wù)運行。

原文標(biāo)題:深入理解Linux內(nèi)核之進程睡眠(下)

文章出處:【微信公眾號:Linux閱碼場】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

責(zé)任編輯:haq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 內(nèi)核
    +關(guān)注

    關(guān)注

    3

    文章

    1384

    瀏覽量

    40442
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11351

    瀏覽量

    210505

原文標(biāo)題:深入理解Linux內(nèi)核之進程睡眠(下)

文章出處:【微信號:gh_6fde77c41971,微信公眾號:FPGA干貨】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    嵌入式學(xué)習(xí)-飛凌嵌入式ElfBoard ELF 1板卡-Linux內(nèi)核移植之內(nèi)核簡介

    用戶提供移植好的板級開發(fā)包。板卡廠商也會對移植好的內(nèi)核版本進行維護,例如一些BUG修復(fù)或者物料替換。接下來講一下獲取這三種源碼的方法:獲取linux官網(wǎng)源碼 地址:https
    發(fā)表于 12-16 13:08

    飛凌嵌入式ElfBoard ELF 1板卡-Linux內(nèi)核移植之內(nèi)核簡介

    用戶提供移植好的板級開發(fā)包。板卡廠商也會對移植好的內(nèi)核版本進行維護,例如一些BUG修復(fù)或者物料替換。接下來講一下獲取這三種源碼的方法:獲取linux官網(wǎng)源碼地址:https
    發(fā)表于 12-13 09:03

    嵌入式工程師都在找的【Linux內(nèi)核調(diào)試技術(shù)】建議收藏!

    在嵌入式系統(tǒng)的開發(fā)中,Linux內(nèi)核調(diào)試是一個至關(guān)重要的環(huán)節(jié)。 隨著處理器技術(shù)的不斷進步和嵌入式領(lǐng)域的蓬勃發(fā)展,掌握有效的內(nèi)核調(diào)試技術(shù)成為了開發(fā)者們的一項必備技能。本文將介紹幾種常見的Lin
    發(fā)表于 11-28 15:37

    國產(chǎn)實時操作系統(tǒng):和RT-Linux,Zephyr的實時性對比

    基于RT-Thread內(nèi)核,并具備POSIX用戶態(tài)運行環(huán)境的高性能實時操作系統(tǒng)。它類似Linux、Windows的架構(gòu),具備用戶
    的頭像 發(fā)表于 11-12 01:07 ?1300次閱讀
    國產(chǎn)實時操作系統(tǒng):和RT-<b class='flag-5'>Linux</b>,Zephyr的實時性對比

    Linux系統(tǒng)中shell命令解析

    shell是Linux系統(tǒng)的用戶界面,提供了用戶內(nèi)核交互的一種接口,它接收用戶輸入的命令并到送到內(nèi)核
    的頭像 發(fā)表于 11-05 15:40 ?384次閱讀

    一文搞懂Linux進程的睡眠和喚醒

    ): 進程在等待某個條件滿足(如I/O操作),可以被信號喚醒。 Linux通過內(nèi)核提供的系統(tǒng)調(diào)用來控制進程的睡眠。常用的系統(tǒng)調(diào)用有: sleep(): 使進程暫停指定的秒數(shù)。 usleep(): 使進程暫停
    發(fā)表于 11-04 15:15

    deepin社區(qū)亮相第19屆中國Linux內(nèi)核開發(fā)者大會

    中國 Linux 內(nèi)核開發(fā)者大會,作為中國 Linux 內(nèi)核領(lǐng)域最具影響力的峰會之一,一直以來都備受矚目。
    的頭像 發(fā)表于 10-29 16:35 ?585次閱讀

    詳解linux內(nèi)核的uevent機制

    linux內(nèi)核中,uevent機制是一種內(nèi)核用戶空間通信的機制,用于通知用戶空間應(yīng)用程序各種硬件更改或其他事件,比如插入或移除硬件設(shè)備(
    的頭像 發(fā)表于 09-29 17:01 ?1005次閱讀

    linux驅(qū)動程序如何加載進內(nèi)核

    Linux系統(tǒng)中,驅(qū)動程序是內(nèi)核與硬件設(shè)備之間的橋梁。它們允許內(nèi)核與硬件設(shè)備進行通信,從而實現(xiàn)對硬件設(shè)備的控制和管理。 驅(qū)動程序的編寫 驅(qū)動程序的編寫是Linux驅(qū)動開發(fā)的基礎(chǔ)。在編
    的頭像 發(fā)表于 08-30 15:02 ?607次閱讀

    Linux內(nèi)核測試技術(shù)

    Linux 內(nèi)核Linux操作系統(tǒng)的核心部分,負責(zé)管理硬件資源和提供系統(tǒng)調(diào)用接口。隨著 Linux 內(nèi)核的不斷發(fā)展和更新,其復(fù)雜性和代碼規(guī)
    的頭像 發(fā)表于 08-13 13:42 ?604次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>測試技術(shù)

    Linux內(nèi)核中的頁面分配機制

    Linux內(nèi)核中是如何分配出頁面的,如果我們站在CPU的角度去看這個問題,CPU能分配出來的頁面是以物理頁面為單位的。也就是我們計算機中常講的分頁機制。本文就看下Linux內(nèi)核是如何管
    的頭像 發(fā)表于 08-07 15:51 ?362次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>中的頁面分配機制

    歡創(chuàng)播報 華為宣布鴻蒙內(nèi)核已超越Linux內(nèi)核

    1 華為宣布鴻蒙內(nèi)核已超越Linux內(nèi)核 ? 6月21日,在華為開發(fā)者大會上, HarmonyOS NEXT(鴻蒙NEXT)——真正獨立于安卓和iOS的鴻蒙操作系統(tǒng),正式登場。這是HarmonyOS
    的頭像 發(fā)表于 06-27 11:30 ?913次閱讀

    使用 PREEMPT_RT 在 Ubuntu 中構(gòu)建實時 Linux 內(nèi)核

    盟通技術(shù)干貨構(gòu)建實時Linux內(nèi)核簡介盟通技術(shù)干貨Motrotech如果需要在Linux中實現(xiàn)實時計算性能,進而有效地將Linux轉(zhuǎn)變?yōu)镽TOS,那么大多數(shù)發(fā)行版都可以打上名為PREE
    的頭像 發(fā)表于 04-12 08:36 ?2819次閱讀
    使用 PREEMPT_RT 在 Ubuntu 中構(gòu)建實時 <b class='flag-5'>Linux</b> <b class='flag-5'>內(nèi)核</b>

    請問如何給STM32MP157上Linux5.4.31打?qū)崟r內(nèi)核補丁?

    我這邊想給STM32MP157芯片A7上面的Linux打?qū)崟r內(nèi)核補丁,從而運行一些對實時性要求較高的應(yīng)用程序。我看到我的Linux內(nèi)核版本是5.4.31的。然而,
    發(fā)表于 03-11 06:09

    psoc6在進入睡眠前配置了spi的口為高阻態(tài),spi無法正常工作是為什么?

    ); } //----------------------------------------------------------- 我發(fā)現(xiàn)一個問題就是我如果在進入睡眠前配置了spi的口為高阻態(tài),在睡眠喚醒后,我的spi重新初
    發(fā)表于 02-21 06:16