自拍偷在线精品自拍偷|国产无码一区二区久久|最新版天堂资源中文官网|国产精品第一页爽爽影院|国产精品一区二区av不卡|久久久波多野av一区无码|国产欧美日本亚洲精品一4区|亚洲精品天堂在线观看2020

當(dāng)前位置:首頁 > 網(wǎng)站建設(shè) > 正文內(nèi)容

linux內(nèi)核源碼目錄(linux內(nèi)核源碼在線閱讀)

網(wǎng)站建設(shè)1年前 (2023-10-13)503

我們?cè)凇?一文看懂Linux性能分析|perf 原理 》一文中介紹過,perf 是基于采樣來對(duì)程序進(jìn)行分析的。采樣的步驟如下:

通過設(shè)置一個(gè)定時(shí)器,定時(shí)器的觸發(fā)時(shí)間可以由用戶設(shè)定。

定時(shí)器被觸發(fā)后,將會(huì)調(diào)用采集函數(shù)收集當(dāng)前運(yùn)行環(huán)境的數(shù)據(jù)(如當(dāng)前正在執(zhí)行的進(jìn)程和函數(shù)等)。

將采集到的數(shù)據(jù)寫入到一個(gè)環(huán)形緩沖區(qū)(ring buffer)中。

應(yīng)用層可以通過內(nèi)存映射來讀取環(huán)形緩沖區(qū)中的采樣數(shù)據(jù)。

通過設(shè)置一個(gè)定時(shí)器,定時(shí)器的觸發(fā)時(shí)間可以由用戶設(shè)定。

定時(shí)器被觸發(fā)后,將會(huì)調(diào)用采集函數(shù)收集當(dāng)前運(yùn)行環(huán)境的數(shù)據(jù)(如當(dāng)前正在執(zhí)行的進(jìn)程和函數(shù)等)。

將采集到的數(shù)據(jù)寫入到一個(gè)環(huán)形緩沖區(qū)(ring buffer)中。

應(yīng)用層可以通過內(nèi)存映射來讀取環(huán)形緩沖區(qū)中的采樣數(shù)據(jù)。

上述步驟如下圖所示:

接下來,我們將會(huì)介紹 perf 在 Linux 內(nèi)核中的實(shí)現(xiàn)。

事件

perf 是基于事件進(jìn)行采樣的,上面所說的定時(shí)器就是其中一種事件,被稱為: CPU時(shí)鐘事件 。除了 CPU 時(shí)鐘事件外,perf 還支持多種事件,如:

上下文切換事件 :當(dāng)調(diào)度器切換進(jìn)程時(shí)觸發(fā)。

缺頁異常事件 :當(dāng)進(jìn)程訪問還沒有映射到物理內(nèi)存的虛擬內(nèi)存地址時(shí)觸發(fā)。

CPU遷移事件 :當(dāng)進(jìn)程從一個(gè) CPU 遷移到另一個(gè) CPU 時(shí)觸發(fā)。

...

展開全文

上下文切換事件 :當(dāng)調(diào)度器切換進(jìn)程時(shí)觸發(fā)。

缺頁異常事件 :當(dāng)進(jìn)程訪問還沒有映射到物理內(nèi)存的虛擬內(nèi)存地址時(shí)觸發(fā)。

CPU遷移事件 :當(dāng)進(jìn)程從一個(gè) CPU 遷移到另一個(gè) CPU 時(shí)觸發(fā)。

...

由于 perf 支持的事件眾多,所以本文只挑選 CPU時(shí)鐘事件 進(jìn)行分析。

1. perf_event 結(jié)構(gòu)體

Linux 內(nèi)核使用 perf_event 結(jié)構(gòu)體來描述一個(gè)事件(如 CPU 時(shí)鐘事件),其定義如下(由于 perf_event 結(jié)構(gòu)體過于龐大,所以對(duì)其進(jìn)行簡(jiǎn)化):

structperf_event{

...

structlist_headevent_entry;

linux內(nèi)核源碼目錄(linux內(nèi)核源碼在線閱讀)

conststructpmu* pmu;

enumperf_event_active_state state;

atomic64_tcount; // 事件被觸發(fā)的次數(shù)

...

structperf_event_attrattr; // 事件的屬性(由用戶提供)

structhw_perf_eventhw;

structperf_event_context* ctx; // 事件所屬的上下文

...

};

我們現(xiàn)在只需關(guān)注其中的兩個(gè)成員變量: count 和 ctx 。

count :表示事件被觸發(fā)的次數(shù)。

ctx :表示當(dāng)前事件所屬的上下文。

count :表示事件被觸發(fā)的次數(shù)。

ctx :表示當(dāng)前事件所屬的上下文。

count 成員變量容易理解,所以就不作詳細(xì)介紹了。我們注意到 ctx 成員變量的類型為 perf_event_context 結(jié)構(gòu),那么這個(gè)結(jié)構(gòu)代表什么?

2. perf_event_context 結(jié)構(gòu)體

因?yàn)橐粋€(gè)進(jìn)程可以同時(shí)分析多種事件,所以就使用 perf_event_context 結(jié)構(gòu)來記錄屬于進(jìn)程的所有事件。我們來看看 perf_event_context 結(jié)構(gòu)的定義,如下所示:

structperf_event_context{

...

structlist_headevent_list; // 連接所有屬于當(dāng)前上下文的事件

intnr_events; // 屬于當(dāng)前上下文的所有事件的總數(shù)

...

structtask_struct* task; // 當(dāng)前上下文屬于的進(jìn)程

...

};

我們對(duì) perf_event_context 結(jié)構(gòu)進(jìn)行了簡(jiǎn)化,下面介紹一下各個(gè)成員的作用:

event_list :連接所有屬于當(dāng)前上下文的事件。

nr_events :屬于當(dāng)前上下文的所有事件的總數(shù)。

task :當(dāng)前上下文所屬的進(jìn)程。

event_list :連接所有屬于當(dāng)前上下文的事件。

nr_events :屬于當(dāng)前上下文的所有事件的總數(shù)。

task :當(dāng)前上下文所屬的進(jìn)程。

perf_event_context 結(jié)構(gòu)通過 event_list 字段把所有屬于本上下文的事件連接起來,如下圖所示:

另外,在進(jìn)程描述結(jié)構(gòu)體 task_struct 中,有個(gè)指向 perf_event_context 結(jié)構(gòu)的指針。如下所示:

structtask_struct{

...

structperf_event_context* perf_event_ctxp;

...

};

這樣,內(nèi)核就能通過進(jìn)程描述結(jié)構(gòu)體的 perf_event_ctxp 成員,來獲取屬于此進(jìn)程的事件列表。

3. pmu 結(jié)構(gòu)體

前面我們說過 perf 支持多種事件,而不同的事件應(yīng)該有不同的啟用和禁用動(dòng)作。為了讓不同的事件有不同的啟用和禁用動(dòng)作,所以內(nèi)核定義了 pmu 結(jié)構(gòu)。其定義如下:

structpmu{

int(*enable) (struct perf_event *event);

void(*disable) (struct perf_event *event);

void(*read) (struct perf_event *event);

...

};

下面介紹一下各個(gè)字段的作用:

enable :?jiǎn)⒂檬录?

disable :禁用事件。

read :事件被觸發(fā)時(shí)的回調(diào)。

enable :?jiǎn)⒂檬录?

disable :禁用事件。

read :事件被觸發(fā)時(shí)的回調(diào)。

perf_event 結(jié)構(gòu)的 pmu 成員是一個(gè)指向 pmu 結(jié)構(gòu)的指針。如果當(dāng)前事件是個(gè) CPU 時(shí)鐘事件時(shí), pmu 成員將會(huì)指向 perf_ops_cpu_clock 變量。

我們來看看 perf_ops_cpu_clock 變量的定義:

staticconststructpmuperf_ops_cpu_clock= {

.enable = cpu_clock_perf_event_enable,

.disable = cpu_clock_perf_event_disable,

.read = cpu_clock_perf_event_read,

};

也就是說:

當(dāng)要啟用一個(gè) CPU 時(shí)鐘事件時(shí),內(nèi)核將會(huì)調(diào)用 cpu_clock_perf_event_enable 函數(shù)來啟用這個(gè)事件。

當(dāng)要禁用一個(gè) CPU 時(shí)鐘事件時(shí),內(nèi)核將會(huì)調(diào)用 cpu_clock_perf_event_disable 函數(shù)來禁用這個(gè)事件。

當(dāng)事件被觸發(fā)時(shí),內(nèi)核將會(huì)調(diào)用 cpu_clock_perf_event_read 函數(shù)來進(jìn)行特定的動(dòng)作。

當(dāng)要啟用一個(gè) CPU 時(shí)鐘事件時(shí),內(nèi)核將會(huì)調(diào)用 cpu_clock_perf_event_enable 函數(shù)來啟用這個(gè)事件。

當(dāng)要禁用一個(gè) CPU 時(shí)鐘事件時(shí),內(nèi)核將會(huì)調(diào)用 cpu_clock_perf_event_disable 函數(shù)來禁用這個(gè)事件。

當(dāng)事件被觸發(fā)時(shí),內(nèi)核將會(huì)調(diào)用 cpu_clock_perf_event_read 函數(shù)來進(jìn)行特定的動(dòng)作。

前面說過,當(dāng)要啟用一個(gè) CPU 時(shí)鐘事件時(shí),內(nèi)核會(huì)調(diào)用 cpu_clock_perf_event_enable 函數(shù)來啟用它。我們來看看 cpu_clock_perf_event_enable 函數(shù)的實(shí)現(xiàn),代碼如下:

staticint

cpu_clock_perf_event_enable(struct perf_event *event)

{

...

perf_swevent_start_hrtimer(event);

return0;

}

從上面代碼可以看出, cpu_clock_perf_event_enable 函數(shù)實(shí)際上調(diào)用了 perf_swevent_start_hrtimer 函數(shù)來進(jìn)行初始化工作。我們?cè)賮砜纯?perf_swevent_start_hrtimer 函數(shù)的實(shí)現(xiàn):

staticvoid

perf_swevent_start_hrtimer(struct perf_event *event)

{

structhw_perf_event* hwc= event- hw;

// 1. 初始化一個(gè)定時(shí)器,定時(shí)器的回調(diào)函數(shù)為:perf_swevent_hrtimer

hrtimer_init(hwc-hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);

hwc-hrtimer.function = perf_swevent_hrtimer;

if(hwc-sample_period) {

...

// 2. 啟動(dòng)定時(shí)器

__hrtimer_start_range_ns(hwc-hrtimer, ns_to_ktime(period), 0,

HRTIMER_MODE_REL, 0);

}

}

從上面的代碼可知, perf_swevent_start_hrtimer 函數(shù)主要完成兩件事情:

初始化一個(gè)定時(shí)器,定時(shí)器的回調(diào)函數(shù)為: perf_swevent_hrtimer 。

啟動(dòng)定時(shí)器。

初始化一個(gè)定時(shí)器,定時(shí)器的回調(diào)函數(shù)為: perf_swevent_hrtimer 。

啟動(dòng)定時(shí)器。

這個(gè)定時(shí)器結(jié)構(gòu)保存在 perf_event 結(jié)構(gòu)的 hwc 成員中,我們?cè)谝院蟮奈恼轮袑?huì)介紹 Linux 高精度定時(shí)器的實(shí)現(xiàn)。

這個(gè)定時(shí)器結(jié)構(gòu)保存在 perf_event 結(jié)構(gòu)的 hwc 成員中,我們?cè)谝院蟮奈恼轮袑?huì)介紹 Linux 高精度定時(shí)器的實(shí)現(xiàn)。

當(dāng)定時(shí)器被觸發(fā)時(shí),內(nèi)核將會(huì)調(diào)用 perf_swevent_hrtimer 函數(shù)來處理事件。我們?cè)賮矸治鲆幌?perf_swevent_hrtimer 函數(shù)的實(shí)現(xiàn):

staticenumhrtimer_restart

perf_swevent_hrtimer(struct hrtimer *hrtimer)

{

enumhrtimer_restart ret = HRTIMER_RESTART;

structperf_sample_datadata;

structpt_regs* regs;

structperf_event* event;

u64 period;

// 獲取當(dāng)前定時(shí)器所屬的事件對(duì)象

event = container_of(hrtimer, struct perf_event, hw.hrtimer);

// 前面說過,如果是CPU時(shí)鐘事件,將會(huì)調(diào)用 cpu_clock_perf_event_read 函數(shù)

event-pmu-read(event);

data.addr = 0;

// 獲取定時(shí)器被觸發(fā)時(shí)所有寄存器的值

regs = get_irq_regs;

...

if(regs) {

if(!(event-attr.exclude_idle current-pid == 0)) {

// 最重要的地方:對(duì)數(shù)據(jù)進(jìn)行采樣

if(perf_event_overflow(event, 0, data, regs))

ret = HRTIMER_NORESTART;

}

}

...

returnret;

}

perf_swevent_hrtimer 函數(shù)最重要的操作就是:調(diào)用 perf_event_overflow 函數(shù)對(duì)數(shù)據(jù)進(jìn)行采樣與收集。 perf_event_overflow 函數(shù)在后面將會(huì)介紹,我們暫時(shí)跳過。

那什么時(shí)候會(huì)啟用事件呢?答案就是:進(jìn)程被調(diào)度到 CPU 運(yùn)行時(shí)。調(diào)用鏈如下:

schedule

└→ context_switch

└→ finish_task_switch

└→ perf_event_task_sched_in

└→ __perf_event_sched_in

└→ group_sched_in

└→ event_sched_in

└→ event-pmu-enable

└→ cpu_clock_perf_event_enable

內(nèi)核通過調(diào)用 schedule 函數(shù)來完成調(diào)度工作。從上面的調(diào)用鏈可知,當(dāng)進(jìn)程選中被調(diào)度到 CPU 運(yùn)行時(shí),最終會(huì)調(diào)用 cpu_clock_perf_event_enable 函數(shù)來啟用這個(gè) CPU 時(shí)鐘事件。

啟用事件的過程如下圖所示:

所以,當(dāng)進(jìn)程被選中并且被調(diào)度運(yùn)行時(shí),內(nèi)核會(huì)啟用屬于此進(jìn)程的 perf 事件。不難看出,當(dāng)進(jìn)程被調(diào)度出 CPU 時(shí)(停止運(yùn)行),內(nèi)核會(huì)禁用屬于此進(jìn)程的 perf 事件。

數(shù)據(jù)采樣

最后,我們來看看 perf 是怎么進(jìn)行數(shù)據(jù)采樣的。

通過上面的分析,我們知道 perf 最終會(huì)調(diào)用 perf_event_overflow 函數(shù)來進(jìn)行數(shù)據(jù)采樣。所以我們來看看 perf_event_overflow 函數(shù)的實(shí)現(xiàn),代碼如下:

int

perf_event_overflow(struct perf_event *event, intnmi,

struct perf_sample_data *data,

struct pt_regs *regs)

{

return__perf_event_overflow(event, nmi, 1, data, regs);

}

可以看出, perf_event_overflow 函數(shù)只是對(duì) __perf_event_overflow 函數(shù)的封裝。我們接著來分析 __perf_event_overflow 函數(shù)的實(shí)現(xiàn):

staticint

__perf_event_overflow(struct perf_event *event, intnmi, intthrottle,

struct perf_sample_data *data, struct pt_regs *regs)

{

...

perf_event_output(event, nmi, data, regs);

returnret;

}

從上面代碼可知, __perf_event_overflow 會(huì)調(diào)用 perf_event_output 函數(shù)來進(jìn)行數(shù)據(jù)采樣。 perf_event_output 函數(shù)的實(shí)現(xiàn)如下:

staticvoid

perf_event_output(struct perf_event *event, intnmi,

struct perf_sample_data *data,

struct pt_regs *regs)

{

structperf_output_handlehandle;

structperf_event_headerheader;

// 進(jìn)行數(shù)據(jù)采樣,并且把采樣到的數(shù)據(jù)保存到data變量中

perf_prepare_sample(header, data, event, regs);

...

// 把采樣到的數(shù)據(jù)保存到環(huán)形緩沖區(qū)中

perf_output_sample(handle, header, data, event);

...

}

perf_event_output 函數(shù)會(huì)進(jìn)行兩個(gè)操作:

調(diào)用 perf_prepare_sample 函數(shù)進(jìn)行數(shù)據(jù)采樣,并且把采樣到的數(shù)據(jù)保存到 data 變量中。

調(diào)用 perf_output_sample 函數(shù)把采樣到的數(shù)據(jù)保存到環(huán)形緩沖區(qū)中。

調(diào)用 perf_prepare_sample 函數(shù)進(jìn)行數(shù)據(jù)采樣,并且把采樣到的數(shù)據(jù)保存到 data 變量中。

調(diào)用 perf_output_sample 函數(shù)把采樣到的數(shù)據(jù)保存到環(huán)形緩沖區(qū)中。

我們來看看 perf 是怎么把采樣到的數(shù)據(jù)保存到環(huán)形緩沖區(qū)的:

void

perf_output_sample(struct perf_output_handle *handle,

struct perf_event_header *header,

struct perf_sample_data *data,

struct perf_event *event)

{

u64 sample_type = data-type;

...

// 1. 保存當(dāng)前IP寄存器地址(用于獲取正在執(zhí)行的函數(shù))

if(sample_type PERF_SAMPLE_IP)

perf_output_put(handle, data-ip);

// 2. 保存當(dāng)前進(jìn)程ID

if(sample_type PERF_SAMPLE_TID)

perf_output_put(handle, data-tid_entry);

// 3. 保存當(dāng)前時(shí)間

if(sample_type PERF_SAMPLE_TIME)

perf_output_put(handle, data-time);

...

// n. 保存函數(shù)的調(diào)用鏈

if(sample_type PERF_SAMPLE_CALLCHAIN) {

if(data-callchain) {

intsize = 1;

if(data-callchain)

size += data-callchain-nr;

size *= sizeof(u64);

perf_output_copy(handle, data-callchain, size);

} else{

u64 nr = 0;

perf_output_put(handle, nr);

}

}

...

}

perf_output_sample 通過調(diào)用 perf_output_put 函數(shù)把用戶感興趣的數(shù)據(jù)保存到環(huán)形緩沖區(qū)中。

用戶感興趣的數(shù)據(jù)是在創(chuàng)建事件時(shí)指定的,例如,如果我們對(duì)函數(shù)的調(diào)用鏈感興趣,那么可以在創(chuàng)建事件時(shí)指定 PERF_SAMPLE_CALLCHAIN 標(biāo)志位。

perf 事件可以通過 pref_event_open 系統(tǒng)調(diào)用來創(chuàng)建,關(guān)于 pref_event_open 系統(tǒng)調(diào)用的使用,讀者可以自行參考相關(guān)的資料。

perf 事件可以通過 pref_event_open 系統(tǒng)調(diào)用來創(chuàng)建,關(guān)于 pref_event_open 系統(tǒng)調(diào)用的使用,讀者可以自行參考相關(guān)的資料。

當(dāng) perf 把采樣的數(shù)據(jù)保存到環(huán)形緩沖區(qū)后,用戶就可以通過 mmap 系統(tǒng)調(diào)用把環(huán)形緩沖區(qū)的數(shù)據(jù)映射到用戶態(tài)的虛擬內(nèi)存地址來進(jìn)行讀取。由于本文只關(guān)心數(shù)據(jù)采樣部分,所以 perf 的其他實(shí)現(xiàn)細(xì)節(jié)可以參考 perf 的源代碼。

數(shù)據(jù)采樣的流程如下圖所示:

總結(jié)

本文主要介紹了 perf 的 CPU 時(shí)鐘事件的實(shí)現(xiàn)原理,另外 perf 除了需要內(nèi)核支持外,還需要用戶態(tài)應(yīng)用程序支持,例如:把采樣到的原始數(shù)據(jù)生成可視化的數(shù)據(jù)或者使用圖形化表現(xiàn)出來。

當(dāng)然,本文主要是介紹 perf 在內(nèi)核中的實(shí)現(xiàn),用戶態(tài)的程序可以參考 Linux 源碼 tools/perf 目錄下的源代碼。

當(dāng)然,perf 是非常復(fù)雜的,本文也忽略了很多細(xì)節(jié)(如果把所有細(xì)節(jié)都闡明,那么篇幅將會(huì)非常長(zhǎng)),所以讀者如果有什么疑問也可以留言討論。

- EOF -

加主頁君微信,不僅Linux技能+1

主頁君日常還會(huì)在個(gè)人微信分享 Linux相關(guān)工具、資源和 精選技術(shù)文章,不定期分享一些 有意思的活動(dòng)、 崗位內(nèi)推以及 如何用技術(shù)做業(yè)余項(xiàng)目

加個(gè)微信,打開一扇窗

點(diǎn)擊標(biāo)題可跳轉(zhuǎn)

1、 Linux 多線程全面解析

2、 一文看懂 Linux 性能分析|perf 原理

3、 淺析 Linux 內(nèi)核 5.1 支持了新的異步 IO 框架 iouring

看完本文有收獲?請(qǐng)分享給更多人

推薦關(guān)注「Linux 愛好者」,提升Linux技能

點(diǎn)贊和在看就是最大的支持??

掃描二維碼推送至手機(jī)訪問。

版權(quán)聲明:本文由飛速云SEO網(wǎng)絡(luò)優(yōu)化推廣發(fā)布,如需轉(zhuǎn)載請(qǐng)注明出處。

本文鏈接:http://m.thonggone.com/post/60300.html

“l(fā)inux內(nèi)核源碼目錄(linux內(nèi)核源碼在線閱讀)” 的相關(guān)文章

山東網(wǎng)站優(yōu)化(濟(jì)南網(wǎng)站優(yōu)化有哪些)

山東網(wǎng)站優(yōu)化(濟(jì)南網(wǎng)站優(yōu)化有哪些)

今天給各位分享山東網(wǎng)站優(yōu)化的知識(shí),其中也會(huì)對(duì)濟(jì)南網(wǎng)站優(yōu)化有哪些進(jìn)行解釋,如果能碰巧解決你現(xiàn)在面臨的問題,別忘了關(guān)注本站,現(xiàn)在開始吧!本文目錄一覽: 1、山東SEO:?jiǎn)雾摼W(wǎng)站怎么做優(yōu)化 2、聊城seo網(wǎng)站優(yōu)化公司找誰 3、山東網(wǎng)站優(yōu)化哪家公司做的比較好? 山東SEO:?jiǎn)雾摼W(wǎng)站怎么做優(yōu)化 1、...

關(guān)于青島網(wǎng)站制作的信息

關(guān)于青島網(wǎng)站制作的信息

今天給各位分享青島網(wǎng)站制作的知識(shí),其中也會(huì)對(duì)進(jìn)行解釋,如果能碰巧解決你現(xiàn)在面臨的問題,別忘了關(guān)注本站,現(xiàn)在開始吧!本文目錄一覽: 1、青島網(wǎng)站建設(shè)哪里好的呢? 2、青島企業(yè)網(wǎng)站搭建怎么制作 3、想知道山東青島好的網(wǎng)站建設(shè)公司有哪些? 4、青島網(wǎng)站制作哪里有 5、青島網(wǎng)站建設(shè)公司哪家不...

網(wǎng)站關(guān)鍵詞優(yōu)化(seo搜索優(yōu)化)

網(wǎng)站關(guān)鍵詞優(yōu)化(seo搜索優(yōu)化)

今天給各位分享網(wǎng)站關(guān)鍵詞優(yōu)化的知識(shí),其中也會(huì)對(duì)seo搜索優(yōu)化進(jìn)行解釋,如果能碰巧解決你現(xiàn)在面臨的問題,別忘了關(guān)注本站,現(xiàn)在開始吧!本文目錄一覽: 1、網(wǎng)站關(guān)鍵字優(yōu)化有哪些方法?應(yīng)該如何做呢? 2、如何 優(yōu)化 一個(gè)網(wǎng)站的 關(guān)鍵詞 3、怎樣做網(wǎng)站關(guān)鍵詞優(yōu)化 4、什么是網(wǎng)站關(guān)鍵詞優(yōu)化 5、...

雙減下的作業(yè)設(shè)計(jì)思路(雙減下的作業(yè)設(shè)計(jì)思路二年級(jí)語文)

雙減下的作業(yè)設(shè)計(jì)思路(雙減下的作業(yè)設(shè)計(jì)思路二年級(jí)語文)

今天給各位分享雙減下的作業(yè)設(shè)計(jì)思路的知識(shí),其中也會(huì)對(duì)雙減下的作業(yè)設(shè)計(jì)思路二年級(jí)語文進(jìn)行解釋,如果能碰巧解決你現(xiàn)在面臨的問題,別忘了關(guān)注本站,現(xiàn)在開始吧!本文目錄一覽: 1、雙減分層布置作業(yè)策略是什么? 2、談?wù)勲p減背景下如何設(shè)計(jì)作業(yè) 3、雙減政策下如何有效布置作業(yè) 4、雙減政策下如何有效...

免費(fèi)的HTML模板下載(免費(fèi)的html模板下載網(wǎng)站)

免費(fèi)的HTML模板下載(免費(fèi)的html模板下載網(wǎng)站)

今天給各位分享免費(fèi)的HTML模板下載的知識(shí),其中也會(huì)對(duì)免費(fèi)的html模板下載網(wǎng)站進(jìn)行解釋,如果能碰巧解決你現(xiàn)在面臨的問題,別忘了關(guān)注本站,現(xiàn)在開始吧!本文目錄一覽: 1、求一個(gè)簡(jiǎn)單的個(gè)人網(wǎng)頁html模板 2、關(guān)于 旅游的 HTML 網(wǎng)頁模板 3、哪里有網(wǎng)站模板免費(fèi)下載,帶后臺(tái)的,謝謝!...

手機(jī)瀏覽器怎么查看網(wǎng)頁源代碼(手機(jī)瀏覽器怎么查看網(wǎng)頁源代碼數(shù)據(jù))

手機(jī)瀏覽器怎么查看網(wǎng)頁源代碼(手機(jī)瀏覽器怎么查看網(wǎng)頁源代碼數(shù)據(jù))

本篇文章給大家談?wù)勈謾C(jī)瀏覽器怎么查看網(wǎng)頁源代碼,以及手機(jī)瀏覽器怎么查看網(wǎng)頁源代碼數(shù)據(jù)對(duì)應(yīng)的知識(shí)點(diǎn),希望對(duì)各位有所幫助,不要忘了收藏本站喔。 本文目錄一覽: 1、怎么用手機(jī)瀏覽器查看網(wǎng)頁源碼 2、怎樣查看網(wǎng)頁源代碼 3、手機(jī)上如何查看網(wǎng)頁代碼 4、網(wǎng)頁如何查看源代碼 5、蘋果手機(jī)怎么能...