在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

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

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

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

聚焦IO,從存儲的角度剖析vim原理

開關(guān)電源芯片 ? 來源:Linux愛好者 ? 作者:Linux愛好者 ? 2021-08-16 11:29 ? 次閱讀

故事起因

無意間用 vim 打開了一個 10 G 的文件,改了一行內(nèi)容,:w 保存了一下,慢的我喲,耗費(fèi)的時間夠泡幾杯茶了。這引起了我的好奇,vim 打開和保存究竟做了啥?
672983a6-f62a-11eb-9bcf-12bb97331649.png

vim — 編輯器之神

vim 號稱編輯器之神,以極其強(qiáng)大的擴(kuò)展性和功能聞名。vi/vim 作為標(biāo)準(zhǔn)的編輯器存在于 Linux 的幾乎每一種發(fā)行版里。vim 的學(xué)習(xí)曲線比較陡峭的,前期必須有一個磨煉的過程。

vim 是一個終端編輯器,在可視化的編輯器橫行的今天,為什么 vim 還如此重要?

因?yàn)?strong>有些場景非它不可,比如線上服務(wù)器終端,除 vi/vim 這種終端編輯器,你別無選擇。

vim 的歷史很悠久,Github 有個文檔歸納了 vim 的歷史進(jìn)程:vim 歷史,Github 開源代碼:代碼倉庫。

筆者今天不講 vim 的用法,這種文章網(wǎng)上隨便搜一大把。筆者將從 vim 的存儲 IO 原理的角度來剖析下 vim 這個神器。

思考幾個小問題,讀者如果感興趣,可以繼續(xù)往下讀哦:

vim 編輯文件的原理是啥,用了啥黑科技嗎?

vim 打開一個 10G 的大型文件,為什么這么慢,里面做了啥?

vim 修改一個 10G 的大型文件,:w 保存的時候,感覺更慢了?為什么?

vim 好像會產(chǎn)生多余的文件?~ 文件 ?.swp 文件 ?都是做啥的呢?

劃重點(diǎn):由于 vim 的功能過于強(qiáng)大,一篇分享根本說不完,本篇文章聚焦 IO,從存儲的角度剖析 vim 原理。

vim 的 io 原理

聲明,系統(tǒng)和 Vim 版本如下:

操作系統(tǒng)版本:Ubuntu 16.04.6 LTSVIM 版本:VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Jul 25 2021 0854)測試文件名:test.txt

vim 就是一個二進(jìn)制程序而已。讀者朋友也可以 Github 下載,編譯,自己調(diào)試哦,效果更佳。

一般使用 vim 編輯文件很簡單,只需要 vim 后面跟文件名即可:

vimtest.txt

這樣就打開了文件,并且可以進(jìn)行編輯。這個命令敲下去,一般情況下,我們就能很快在終端很看到文件的內(nèi)容了。

67eaa68a-f62a-11eb-9bcf-12bb97331649.png

這個過程發(fā)生了什么?先明確下,vim test.txt 到底是啥意思?

本質(zhì)就是運(yùn)行一個叫做 vim 的程序,argv[1] 參數(shù)是 test.txt 嘛。跟你以前寫的 helloworld 程序沒啥不一樣,只不過 vim 這個程序可以終端人機(jī)交互。

所以這個過程無非就是一個進(jìn)程初始化的過程,由 main 開始,到 main_loop(后臺循環(huán)監(jiān)聽)。

1vim 進(jìn)程初始化

vim 有一個 main.c 的入口文件,main 函數(shù)就定義在這里。首先會做一下操作系統(tǒng)相關(guān)的初始化( mch 是 machine 的縮寫):

mch_early_init();

然后會,做一下賦值參數(shù),全局變量的初始化:

/*
*Variousinitialisationssharedwithtests.
*/
common_init(&params);

舉個例子 test.txt 這樣的參數(shù)必定要賦值到全局變量中,因?yàn)橐院笫且?jīng)常使用的。

另外類似于命令的 map 表,是靜態(tài)定義好了的:

staticstructcmdname
{
char_u*cmd_name;//nameofthecommand
ex_func_Tcmd_func;//functionforthiscommand
long_ucmd_argt;//flagsdeclaredabove
cmd_addr_Tcmd_addr_type;//flagforaddresstype
}cmdnames[]={

EXCMD(CMD_write,"write",ex_write,
EX_RANGE|EX_WHOLEFOLD|EX_BANG|EX_FILE1|EX_ARGOPT|EX_DFLALL|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
ADDR_LINES),

}

劃重點(diǎn)::w,:write,:saveas 這樣的 vim 命令,其實(shí)是對應(yīng)到定義好的 c 回調(diào)函數(shù):ex_write 。 ex_write 函數(shù)是數(shù)據(jù)寫入的核心函數(shù)。再比如,:quit 對應(yīng) ex_quit ,用于退出的回調(diào)。

換句話說,vim 里面支持的類似 :w ,的命令,其實(shí)在初始化的時候就確定了。人為的交互只是輸入字符串,vim 進(jìn)程從終端讀到字符串之后,找到對應(yīng)的回調(diào)函數(shù),執(zhí)行即可。再來,會初始化一些 home 目錄,當(dāng)前目錄等變量。

init_homedir();//findrealvalueof$HOME
//保存交互參數(shù)
set_argv_var(paramp->argv,paramp->argc);

配置一下跟終端窗口顯示相關(guān)的東西,這部分主要是一些終端庫相關(guān)的:

//初始化終端一些配置
termcapinit(params.term);//setterminalnameandgetterminal
//初始化光標(biāo)位置
screen_start();//don'tknowwherecursorisnow
//獲取終端的一些信息
ui_get_shellsize();//initsRowsandColumns

再來會加載 .vimrc 這樣的配置文件,讓你的 vim 與眾不同。

//Sourcestartupscripts.
source_startup_scripts(¶ms);

還會加載一些 vim 插件 source_in_path ,使用 load_start_packages 加載 package 。

下面這個就是第一個交互了,等待用戶敲下 enter 鍵:

wait_return(TRUE);

我們經(jīng)常看見的:“Press ENTER or type command to continue“ 就是在這里執(zhí)行的。確認(rèn)完,就說明你真的是要打開文件,并顯示到終端了。

怎么打開文件?怎么顯示字符到終端屏幕?

這一切都來自于 create_windows 這個函數(shù)。名字也很好理解,就是初始化的時候創(chuàng)建終端窗口來著。

/*
*Createtherequestednumberofwindowsandeditbuffersinthem.
*Alsodoesrecoveryif"recoverymode"set.
*/
create_windows(¶ms);

這里其實(shí)涉及到兩個方面:

把數(shù)據(jù)讀出來,讀到內(nèi)存;

把字符渲染到終端;

怎么把數(shù)據(jù)從磁盤上讀出來,就是 IO。怎么渲染到終端這個我們不管,這個使用的是 termlib 或者 ncurses 等終端編程庫來實(shí)現(xiàn)的,感興趣的可以了解下。

這個函數(shù)會調(diào)用到我們的第一個核心函數(shù):open_buffer ,這個函數(shù)做兩個時間:

create memfile:創(chuàng)建一個 memory + .swp 文件的抽象層,讀寫數(shù)據(jù)都會過這一層;

read file:讀原始文件,并解碼(用于顯示到屏幕);

函數(shù)調(diào)用棧:

->readfile
->open_buffer
->create_windows
->vim_main2
->main

真正干活的是 readfile 這個函數(shù),吐槽一下,readfile 是一個 2533 行的函數(shù)。。。。。。

readfile 里面會擇機(jī)創(chuàng)建 swp 文件(以前有的話,可以用于恢復(fù)數(shù)據(jù)),調(diào)用的是 ml_open_file 這個函數(shù),文件創(chuàng)建好之后,size 占用 4k,里面主要是一些特定的元數(shù)據(jù)(用來恢復(fù)數(shù)據(jù)用的)。

劃重點(diǎn):.{文件名}.swp 這個隱藏文件是有格式的,前 4k 為 header,后面的內(nèi)容也是按照一個個block 組織的。

再往后走,會調(diào)用到 read_eintr 這個函數(shù),讀取數(shù)據(jù)的內(nèi)容:

long
read_eintr(intfd,void*buf,size_tbufsize)
{
longret;
for(;;){
ret=vim_read(fd,buf,bufsize);
if(ret>=0||errno!=EINTR)
break;
}
returnret;
}

這是一個最底層的函數(shù),是系統(tǒng)調(diào)用 read 的一個封裝,讀出來之后。這里回答了一個關(guān)鍵問題:vim 的存儲原理是啥?

劃重點(diǎn):本質(zhì)上調(diào)用 read,write,lseek 這樣樸素的系統(tǒng)調(diào)用,而已。

readfile 會把二進(jìn)制的數(shù)據(jù)讀出來,然后進(jìn)行字符轉(zhuǎn)變編碼(按照配置的模式),編碼不對就是亂碼嘍。每次都是按照一個固定 buffer 讀數(shù)據(jù)的,比如 8192 。

劃重點(diǎn):readfile 會讀完文件。這就是為什么當(dāng) vim 打開一個超大文件的時候,會非常慢的原因。

這里提一點(diǎn)題外話:memline 這個封裝是文件之上的,vim 修改文件是修改到內(nèi)存 buffer ,vim 按照策略來 sync memfile 到 swp 文件,一個是防止丟失未保存的數(shù)據(jù),第二是為了節(jié)省內(nèi)存。

mf_write 把內(nèi)存數(shù)據(jù)寫到文件。在 .test.txt.swp 中的就是這樣的數(shù)據(jù)結(jié)構(gòu):

67f34bbe-f62a-11eb-9bcf-12bb97331649.png

block 0 的 header 主要標(biāo)識:

vim 的版本;

編輯文件的路徑;

字符編碼方式;

這里實(shí)現(xiàn)提一個重要知識點(diǎn):swp 文件里存儲的是 block,block 的管理是以一個樹形結(jié)構(gòu)進(jìn)行管理的。block 有 3 種類型:

block0:頭部 4k ,主要是存儲一些文件的元數(shù)據(jù),比如路徑,編碼模式,時間戳等等;

pointer block:樹形內(nèi)部節(jié)點(diǎn);

data block:樹形葉子節(jié)點(diǎn),存儲用戶數(shù)據(jù);

2敲下 :w 背后的原理

進(jìn)程初始化我們講完了,現(xiàn)在來看下 :w 觸發(fā)的調(diào)用吧。用戶敲下 :w 命令觸發(fā) ex_write 回調(diào)(初始化的時候配置好的)。所有的流程皆在 ex_write ,我們來看下這個函數(shù)做了什么。

先撇開代碼實(shí)現(xiàn)來說,用戶敲下 :w 命令其實(shí)只是想保存修改而已

那么第一個問題?用戶的修改在哪里?

在 memline 的封裝,只要沒執(zhí)行過 :w 保存,那么用戶的修改就沒修改到原文件上(注意哦,沒保存之前,一定沒修改原文件哦),這時候,用戶的修改可能在內(nèi)存,也可能在 swp 文件。存儲的數(shù)據(jù)結(jié)構(gòu)為 block 。所以,:w 其實(shí)就是把 memline 里面的數(shù)據(jù)刷到用戶文件而已。怎么刷?

重點(diǎn)步驟如下(以 test.txt 舉例)

創(chuàng)建一個 backup 文件( test.txt~ ),把原文件拷貝出來;

把原文件 test.txt truancate 截?cái)酁?0,相當(dāng)于清空原文件數(shù)據(jù);

從 memline (內(nèi)存 + .test.txt.swp)拷貝數(shù)據(jù),重新寫入原文件 test.txt;

刪除備份文件 test.txt~;

以上就是 :w 做的所有事情了,下面我們看下代碼。

觸發(fā)的回調(diào)是 ex_write ,核心的函數(shù)是 buf_write ,這個函數(shù) 1987 行。

在這函數(shù),會使用 mch_open 創(chuàng)建一個 backup 文件,名字后面帶個 ~ ,比如 test.txt~ ,

bfd=mch_open((char*)backup

拿到 backup 文件的句柄,然后拷貝數(shù)據(jù)(就是一個循環(huán)嘍), 每 8K 操作一次,從 test.txt 拷貝到 test.txt~ ,以做備份。

劃重點(diǎn):如果是 test.txt 是超大文件,那這里就慢了哦。

backup 循環(huán)如下:

//buf_write
while((write_info.bw_len=read_eintr(fd,copybuf,WRITEBUFSIZE))>0)
{
if(buf_write_bytes(&write_info)==FAIL)
//如果失敗,則終止
//否則直到文件結(jié)束
}
}

我們看到,干活的是 buf_write_bytes ,這是 write_eintr 的封裝函數(shù),其實(shí)也就是系統(tǒng)調(diào)用 write 的函數(shù),負(fù)責(zé)寫入一個 buffer 的數(shù)據(jù)到磁盤文件。

longwrite_eintr(intfd,void*buf,size_tbufsize){
longret=0;
longwlen;

while(ret

backup 文件拷貝完成之后,就可以準(zhǔn)備動原文件了。

思考:為什么要先文件備份呢?

留條后路呀,搞錯了還有的恢復(fù),這個才是真正的備份文件。

修改原文件之前的第一步,ftruncate 原文件到 0,然后,從 memline (內(nèi)存 + swp)中拷貝數(shù)據(jù),寫回原文件。

劃重點(diǎn):這里又是一次文件拷貝,超大文件的時候,這里可能巨慢哦。

for(lnum=start;lnum<=?end;?++lnum)
{
????//?從?memline?中獲取數(shù)據(jù),返回一個內(nèi)存?buffer(?memline?其實(shí)就是內(nèi)存和?swap?文件的一個封裝)
????ptr?=?ml_get_buf(buf,?lnum,?FALSE)?-?1;

????//?將這個內(nèi)存?buffer?寫到原文件
????if?(buf_write_bytes(&write_info)?==?FAIL)
????{
????????end?=?0;????????//?write?error:?break?loop
????????break;
????}
????//?...
}

劃重點(diǎn):vim 并不是調(diào)用 pwrite/pread 這樣的調(diào)用來修改原文件,而是把整個文件清空之后,copy 的方式來更新文件。漲知識了。

這樣就完成了文件的更新啦,最后只需要刪掉 backup 文件即可。

//Removethebackupunless'backup'optionissetortherewasa
//conversionerror.
mch_remove(backup);

這個就是我們數(shù)據(jù)寫入的完整流程啦。是不是沒有你想的那么簡單!

簡單小結(jié)下:當(dāng)修改了 test.txt 文件,調(diào)用 :w 寫入保存數(shù)據(jù)的時候發(fā)生了什么?

人機(jī)交互,:w 觸發(fā)調(diào)用 ex_write 回調(diào)函數(shù),于 do_write -> buf_write 完成寫入 ;

具體操作是:先備份一個 test.txt~ 文件出來(全拷貝);

接著,原文件 test.txt 截?cái)酁?0,從 memline( 即 內(nèi)存最新數(shù)據(jù) + .test.txt.swap 的封裝)拷貝數(shù)據(jù),寫入 test.txt (全拷貝) ;

數(shù)據(jù)組織結(jié)構(gòu)

之前講的太細(xì)節(jié),我們從數(shù)據(jù)組織的角度來解釋下。vim 針對用戶對文件的修改,在原文件之上,封裝了兩層抽象:memline,memfile 。分別對應(yīng)文件 memline.c ,memfile.c 。

6815ab0a-f62a-11eb-9bcf-12bb97331649.png

先說 memline 是啥?

對應(yīng)到文本文件中的每一行,memline 是基于 memfile 的。

memline 基于 memfile,那 memfile 又是啥?

這個是一個虛擬內(nèi)存空間的實(shí)現(xiàn),vim 把整個文本文件映射到內(nèi)存中,通過自己管理的方式。這里的單位為 block,memfile 用二叉樹的方式管理 block 。block 不定長,block 由 page 組成,page 為定長 4k 大小

這是一個典型虛擬內(nèi)存的實(shí)現(xiàn)方案,編輯器的修改都體現(xiàn)為對 memfile 的修改,修改都是修改到 block 之上,這是一個線性空間,每個 block 對應(yīng)到文件的要給位置,有 block number 編號,vim 通過策略會把 block 從內(nèi)存中換出,寫入到 swp 文件,從而節(jié)省內(nèi)存。這就是 swap 文件的名字由來。

block 區(qū)分 3 種類型:

block 0 塊:樹的根,文件元數(shù)據(jù);

pointer block:樹的分支,指向下一個 block;

data block:樹的葉子節(jié)點(diǎn),存儲用戶數(shù)據(jù);

swap 文件組織:

681f61fe-f62a-11eb-9bcf-12bb97331649.png

block 0 是特殊塊,結(jié)構(gòu)體占用 1024 個字節(jié)內(nèi)存,寫到文件是按照 1 個page 對齊的,所以是 4096 個字節(jié)。如下圖:

682a4fe2-f62a-11eb-9bcf-12bb97331649.png

block 其他兩種類型:

pointer 類型:這個是中間的分支節(jié)點(diǎn),指向 block 的;

data 類型:這個是葉子節(jié)點(diǎn);

#defineDATA_ID(('d'<

這個 ID 相當(dāng)于魔數(shù),在 swp 文件中很容易識別出來,比如在下面的文件中第一個 4k 存儲的是 block0,第二個 4k 存儲的是 pointer 類型的 block。

6838962e-f62a-11eb-9bcf-12bb97331649.png

第三,第四個 4k 存儲的是一個 data 類型的 block ,里面存儲了原文件數(shù)據(jù)。

68421f96-f62a-11eb-9bcf-12bb97331649.png

當(dāng)用戶修改一行的時候,對應(yīng)到 memline 的一個 line 的修改,對應(yīng)到這行 line 在哪個 block 的修改,從而定期的刷到 swap 文件。

684dda34-f62a-11eb-9bcf-12bb97331649.png

vim 特殊的文件 ~ 和 .swp ?

假設(shè)原文件名稱:test.txt 。

1test.txt~ 文件

test.txt~ 文件估計(jì)很多人都沒見過,因?yàn)橄У奶炝恕_@個文件在修改原文件之前生成,修改原文件之后刪除。作用于只存在于 buf_write ,是為了安全備份的。

劃重點(diǎn):test.txt~ 和 test.txt 本質(zhì)是一樣的,沒有其他特定格式,是用戶數(shù)據(jù)。

讀者朋友試試 vim 一個 10 G的文件,然后改一行內(nèi)容,:w 保存,應(yīng)該很容易發(fā)現(xiàn)這個文件(因?yàn)閭浞莺突貙憰r間巨長 )。

2.test.txt.swp 文件

這個文件估計(jì)絕大多數(shù)人都見過,.swp 文件生命周期存在于整個進(jìn)程的生命周期,句柄是一直打開的。很多人認(rèn)為 .test.txt.swp 是備份文件,其實(shí)準(zhǔn)確來講并不是備份文件,這是為了實(shí)現(xiàn)虛擬內(nèi)存空間的交換文件,test.txt~ 才是真正的備份文件。swp 是 memfile 的一部分,前面 4k 為 header 元數(shù)據(jù),后面的為 一個個 4k 的數(shù)據(jù)行封裝。和用戶數(shù)據(jù)并不完全對應(yīng)。

memfile = 內(nèi)存 + swp 才是最新的數(shù)據(jù)。

思考解答

1vim 存儲原理是啥?

沒啥,就是用的 read,write 這樣的系統(tǒng)調(diào)用來讀寫數(shù)據(jù)而已。

2vim 的過程有兩種冗余的文件?

test.txt~ :是真正的備份文件,誕生于修改原文件之前,消失于修改成功之后;.test.txt.swp :swap 文件,由 block 組成,里面可能由用戶未保存的修改,等待:w 這種調(diào)用,就會覆蓋到原文件;

3vim 編輯超大文件的時候?yàn)槭裁绰?/strong>

一般情況下,你能直觀感受到,慢在兩個地方:

vim 打開的時候;

修改了一行內(nèi)容,:w 保存的時候;

先說第一個場景:vim 一個 10G 的文件,你的直觀感受是啥?

我的直觀感受是:命令敲下之后,可以去泡杯茶,等茶涼了一點(diǎn),差不多就能看到界面了。為什么?

在進(jìn)程初始化的時候,初始化窗口之前,create_windows -> open_buffer 里面調(diào)用 readfile 會把整個文件讀一遍(完整的讀一遍),在屏幕上展示編碼過的字符。

劃重點(diǎn):初始化的時候,readfile 會把整個文件讀一遍。 10 G的文件,你可想而知有多慢。我們可以算一下,按照單盤硬件 100 M/s 的帶寬來算,也要 102 秒的時間。

再說第二個場景:喝了口茶,改了一個單詞,:w 保存一下,媽呀,命令敲下之后,又可以去泡杯茶了?為什么?

先拷貝出一個 10G 的 test.txt~ 備份文件,102 秒就過去了;

test.txt 截?cái)酁?0,再把 memfile( .test.txt.swp )拷貝回 test.txt ,數(shù)據(jù)量 10 G,102 秒過去了(第一次可能更慢哦);

4vim 編輯大文件的時候,會有空間膨脹?

是的,vim 一個 test.txt 10 G 的文件,會存在某個時刻,需要 >=30 G 的磁盤空間。

原文件 test.txt 10 G

備份文件 test.txt~ 10G

swap 文件 .test.txt.swp >10G

總結(jié)

vim 編輯文件并不沒有用黑魔法,還是用的 read,write,樸實(shí)無華

vim 編輯超大文件,打開很慢,因?yàn)闀?strong>讀一遍文件( readfile ),保存的時候很慢,因?yàn)闀?strong>讀寫兩遍文件(backup 一次,memfile 覆蓋寫原文件一次);

memfile 是 vim 抽象的一層虛擬存儲空間(物理上由內(nèi)存 block 和 swp 文件組成)對應(yīng)一個文件的最新修改,存儲單元由 block 構(gòu)成。:w 保存的時候,就是從 memfile 讀,寫到原文件的過程;

memline 是基于 memfile 做的另一層封裝,把用戶的文件抽象成“行”的概念;

.test.txt.swp 文件是一直 open 的,memfile 會定期的交換數(shù)據(jù)進(jìn)去,以便容災(zāi)恢復(fù);

test.txt~ 文件才是真正的備份文件,誕生于 :w 覆蓋原文件之前,消失于成功覆寫原文件之后;

vim 基本都是整個文件的處理,并不是局部處理,大文件的編輯根本不適合 vim ,話說回來,正經(jīng)人誰會用 vim 編輯 10 G 的文件?vim 就是個文本編輯器呀;

一個 readfile 函數(shù) 2533 行,一個 buf_write 函數(shù) 1987 行代碼。。。不是我打擊各位的積極性,這。。。反正我不想再看見它了。。。

后記

對于 vim 的好奇讓筆者擼了一遍源碼,學(xué)習(xí)了下其中的 IO 知識,不想被動輒幾千行一個的函數(shù)教育了一番。我再也不想擼它了。。你學(xué) fei 了嗎?

編輯:hfy

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

    關(guān)注

    13

    文章

    4507

    瀏覽量

    87112
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11469

    瀏覽量

    212899

原文標(biāo)題:Linux 編輯器之神 vim 的 IO 存儲原理

文章出處:【微信號:gh_3980db2283cd,微信公眾號:開關(guān)電源芯片】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦
    熱點(diǎn)推薦

    數(shù)電的角度去分析幾種IO口模式

    上了課感覺也有必要加深理論知識。所以我想從數(shù)電的角度去分析幾種IO口模式。通過對51的學(xué)習(xí)再映射到對其他芯片的認(rèn)識,加深自己對IO口配置的理解。1.P0口P0端口由鎖存器、輸入緩沖器、切換開關(guān)、一個
    發(fā)表于 12-07 07:12

    結(jié)構(gòu)深、角度大、反射差?用共聚焦顯微鏡就對啦!

    和共聚焦3D顯微形貌檢測技術(shù),廣泛應(yīng)用于涉足超精密加工領(lǐng)域的三維形貌檢測與表面質(zhì)量檢測方案。其中,VT6000系列共聚焦顯微鏡,在結(jié)構(gòu)復(fù)雜且反射率低的表面3D微觀形貌重構(gòu)與檢測方面具有不俗的表現(xiàn)。 一
    發(fā)表于 08-04 16:12

    VIM培訓(xùn)教程

    VIM培訓(xùn)教程.rar VIM的歷史 Bram Moolenaar 在 80 年代末購入他的 Amiga 計(jì)算機(jī)時,Amiga 上還沒有他最常用的編輯器 vi。Bram 從一個開源的 vi 復(fù)制 Stevie 開始,開發(fā)
    發(fā)表于 03-13 14:14 ?0次下載

    VIM for windows

    VIM for windows Vim目前已經(jīng)有類Unix版和Windows版,盡管vim較vi已經(jīng)改良了不少,但是初次使用還是會一頭霧水,不知如何操作,所以學(xué)習(xí)vim要首先過2關(guān)。
    發(fā)表于 03-13 14:41 ?30次下載

    VIM高級技巧

    VIM高級技巧
    發(fā)表于 10-29 11:06 ?9次下載
    <b class='flag-5'>VIM</b>高級技巧

    Vim使用技巧總結(jié)

    轉(zhuǎn)眼上vim的“賊船”有一年多了。PHP到C,都在用。想要真正用vim于日常的編碼工作,必然需要一些插件的支持。不過本文并不打算總結(jié)插件,筆者認(rèn)為 vim 的兩個精髓:組合和重復(fù)跟插
    的頭像 發(fā)表于 06-06 09:20 ?3266次閱讀

    不同應(yīng)用程序的存儲IO類型解析

    的數(shù)據(jù)訪問類型有所不同。 本文描述典型的不同應(yīng)用程序的存儲IO類型。幫助讀者了解不同應(yīng)用程序存儲IO類型的同時,提供的數(shù)據(jù)也可以為存儲模擬和
    的頭像 發(fā)表于 11-30 15:21 ?2468次閱讀
    不同應(yīng)用程序的<b class='flag-5'>存儲</b><b class='flag-5'>IO</b>類型解析

    pathogen.vim Vim插件

    ./oschina_soft/vim-pathogen.zip
    發(fā)表于 05-24 10:21 ?0次下載
    pathogen.<b class='flag-5'>vim</b> <b class='flag-5'>Vim</b>插件

    vim-go Vim的Go開發(fā)插件

    ./oschina_soft/vim-go.zip
    發(fā)表于 05-24 09:42 ?1次下載
    <b class='flag-5'>vim</b>-go <b class='flag-5'>Vim</b>的Go開發(fā)插件

    vim-switchtoinc Vim插件

    ./oschina_soft/vim-switchtoinc.zip
    發(fā)表于 05-24 09:19 ?3次下載
    <b class='flag-5'>vim</b>-switchtoinc <b class='flag-5'>Vim</b>插件

    vim-vala vim的vala擴(kuò)展

    ./oschina_soft/vim-vala.zip
    發(fā)表于 05-24 16:57 ?3次下載
    <b class='flag-5'>vim</b>-vala <b class='flag-5'>vim</b>的vala擴(kuò)展

    Vim之父去世后,Vim項(xiàng)目誰來接管?

    一直以來,Bram Moolenaar 被稱為 Vim 項(xiàng)目的 BDFL(Benevolent Dictator For Life,終身仁慈獨(dú)裁者),管理著 Vim 項(xiàng)目的各個方面,他的去世讓無數(shù)使用過 Vim 的用戶感到痛心,
    的頭像 發(fā)表于 08-15 15:07 ?936次閱讀
    <b class='flag-5'>Vim</b>之父去世后,<b class='flag-5'>Vim</b>項(xiàng)目誰來接管?

    vim編輯器如何使用

    Vim編輯器是一個功能強(qiáng)大的文本編輯器,它基于Vi進(jìn)行改進(jìn),并增加了許多新特性。Vim編輯器的使用主要涉及其不同的工作模式及相應(yīng)操作。以下是Vim編輯器的基本使用方法: 一、Vim編輯
    的頭像 發(fā)表于 08-30 14:58 ?817次閱讀

    服務(wù)器數(shù)據(jù)恢復(fù)—數(shù)據(jù)恢復(fù)的角度討論RAID磁盤陣列的存儲安全問題

    出于盡可能避免數(shù)據(jù)災(zāi)難的設(shè)計(jì)初衷,RAID解決了3個問題:容量問題、IO性能問題、存儲安全(冗余)問題。數(shù)據(jù)恢復(fù)的角度討論RAID的存儲
    的頭像 發(fā)表于 09-07 10:21 ?495次閱讀

    λ-IO:存儲計(jì)算下的IO棧設(shè)計(jì)

    動機(jī)和背景? ? 存儲計(jì)算存儲資源的充分利用。IO棧是管理存儲器的的基本組件,包括設(shè)備驅(qū)動、塊接口層、文件系統(tǒng),目前一些用戶空間IO庫(如S
    的頭像 發(fā)表于 12-02 10:35 ?574次閱讀
    λ-<b class='flag-5'>IO</b>:<b class='flag-5'>存儲</b>計(jì)算下的<b class='flag-5'>IO</b>棧設(shè)計(jì)
    主站蜘蛛池模板: 欧美人与动另类在线 | 美女国产精品 | 亚洲影视自拍揄拍愉拍 | 特级片在线观看 | 性喷潮久久久久久久久 | 久久久久久国产精品免费 | 国模私拍视频在线 | 手机精品视频在线观看免费 | 婷婷香蕉 | 你懂的 在线观看 | 黄色网址播放 | 国产在线观看www鲁啊鲁免费 | 精品免费视在线视频观看 | 亚洲高清在线视频 | 91成人免费视频 | 日a在线 | 免费看毛片网 | 午夜性刺激免费视频观看不卡专区 | 久草在线免费资源站 | 亚洲va国产va天堂va久久 | 高清一区高清二区视频 | 萝l在线精品社区资源 | 久久成人综合网 | 1024手机看片日韩 | 午夜肉伦伦影院 | 国产精品夜色一区二区三区 | 女bbbbxxxx视频| 综合六月 | 综合网视频 | 国产网站免费视频 | 精品国产高清在线看国产 | 天天射天天操天天色 | 天天操丝袜 | 色婷婷一区二区三区四区成人 | 巨臀中文字幕一区二区翘臀 | 日本免费大黄在线观看 | 国产国产人免费人成成免视频 | 欧美精品一区二区三区在线播放 | 男女视频免费观看 | 伊人久久大香线蕉综合7 | 国产手机视频在线 |