日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux必懂知识大总结(下)

發布時間:2023/12/13 linux 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux必懂知识大总结(下) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

AWK/SED

awk

awk是一個強大的文本分析工具,相對于grep的查找,sed的編輯,awk在其對數據分析并生成報告時,顯得尤為強大。簡單來說awk就是把文件逐行的讀入,以空格為默認分隔符將每行切片,切開的部分再進行各種分析處理。

awk '{pattern + action}' {filenames}

?

統計ip

cat test.txt | awk '{print $2}' | sort | uniq -c | sort -n -r | head -n 1

sed 編輯文本

sed -e 's/foo/bar/' myfile

將 myfile 文件中每行第一次出現的foo用字符串bar替換,然后將該文件內容輸出到標準輸出

sed -e 's/foo/bar/g' myfile

g 使得 sed 對文件中所有符合的字符串都被替換

sed -i 's/foo/bar/g' myfile

選項 i 使得 sed 修改文件

sed -i 's/foo/bar/g' ./m*

批量操作當前目錄下以 m 開頭的文件

sed -i 's/foo/bar/g' `grep foo -rl --include="m*" ./`

``括起來的grep命令,表示將grep命令的的結果作為操作文件

grep 命令中,選項r表示查找所有子目錄,l表示僅列出符合條件的文件名,用來傳給sed命令做操作,--include="m*" 表示僅查找 m 開頭的文件

管道

管道是linux提供的一種常見的進程通信工具

管道中的數據只能讀取一次

管道的實現并沒有使用專門的數據結構,而是借助了文件系統的file結構和VFS的索引節點inode。通過將兩個 file 結構指向同一個臨時的 VFS 索引節點,而這個 VFS 索引節點又指向一個物理頁面而實現的。

IO模型

mmap

零拷貝技術:讓數據傳輸不需要經過user space 使用mmap

mmap系統調用導致文件的內容通過DMA模塊被復制到內核緩沖區中,該緩沖區之后與用戶進程共享,這樣就內核緩沖區與用戶緩沖區之間的復制就不會發生。

sendfile

ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);

?

參數特別注意的是:in_fd必須是一個支持mmap函數的文件描述符,也就是說必須指向真實文件,不能使用socket描述符和管道。

out_fd必須是一個socket描述符。

由此可見sendfile幾乎是專門為在網絡上傳輸文件而設計的。

?

Sendfile 函數在兩個文件描述符之間直接傳遞數據(完全在內核中操作,傳送),從而避免了內核緩沖區數據和用戶緩沖區數據之間的拷貝,操作效率很高,被稱之為零拷貝。

?

select poll(NIO)

select poll epoll都是IO多路復用的實現方式!

select系統調用的目的是:在一段指定時間內,監聽用戶感興趣的文件描述符上的可讀、可寫和異常(異常不包括網絡斷開)事件。poll和select應該被歸類為這樣的系統調用,它們可以阻塞地同時探測一組支持非阻塞的IO設備,直至某一個設備觸發了事件或者超過了指定的等待時間——也就是說它們的職責不是做IO,而是幫助調用者尋找當前就緒的設備

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

?

fd_set結構體是文件描述符集,該結構體實際上是一個整型數組,數組中的每個元素的每一位標記一個文件描述符。fd_set能容納的文件描述符數量由FD_SETSIZE指定,一般情況下,FD_SETSIZE等于1024,這就限制了select能同時處理的文件描述符的總量。

?

1)nfds參數指定被監聽的文件描述符的總數。通常被設置為select監聽的所有文件描述符中最大值加1;

2)readfds、writefds、exceptfds分別指向可讀、可寫和異常等事件對應的文件描述符集合。這三個參數都是傳入傳出型參數,指的是在調用select之前,用戶把關心的可讀、可寫、或異常的文件描述符通過FD_SET函數分別添加進readfds、writefds、exceptfds文件描述符集,select將對這些文件描述符集中的文件描述符進行監聽,如果有就緒文件描述符,select會重置readfds、writefds、exceptfds文件描述符集來通知應用程序哪些文件描述符就緒。這個特性將導致select函數返回后,再次調用select之前,必須重置我們關心的文件描述符,也就是三個文件描述符集已經不是我們之前傳入 的了。

3)timeout參數用來指定select函數的超時時間。

?

1)如果指定timeout為NULL,select會永遠等待下去,直到有一個文件描述符就緒,select返回;

2)如果timeout的指定時間為0,select根本不等待,立即返回;

3)如果指定一段固定時間,則在這一段時間內,如果有指定的文件描述符就緒,select函數返回,如果超過指定時間,select同樣返回。

?

select的幾大缺點:

1)每次調用select,都需要把fd集合從用戶態拷貝到內核態,這個開銷在fd很多時會很大

2)每次調用select都需要在內核遍歷傳遞進來的所有fd,這個開銷在fd很多時也很大(不適合服務器,但客戶端也可以使用)

3)select支持的文件描述符數量太小了,默認是1024

?

?

int poll(struct pollfd *fds, nfds_t nfds, int timeout);

與select非常類似,poll比select的好處就是沒有描述符數量限制,select 有1024 的限制,描述符不能超過此值,poll不受限制。

此函數在系統調用select內部被使用,作用是把當前的文件指針掛到設備內部定義的等待

隊列中。

?

send不是立即發送數據,而是將數據放在本地網卡緩沖區中。

epoll(NIO)

select,poll還是在應用中輪詢Socket,容易浪費;OS會自動輪詢,通過epoll_wait返回。

epoll 與select和poll在使用和實現上有很大區別。首先,epoll使用一組函數來完成,而不是單獨的一個函數;其次,epoll把用戶關心的文件描述符上的事件放在內核里的一個事件表中,無須向select和poll那樣每次調用都要重復傳入文件描述符集合事件集。

?

系統調用:

epoll_create 創建一個epoll對象,一般epollfd = epoll_create()

?

epoll_ctl (epoll_add/epoll_del的合體),往epoll對象中增加/刪除某一個流的某一個事件

比如

epoll_ctl(epollfd, EPOLL_CTL_ADD, socket, EPOLLIN);//注冊緩沖區非空事件,即有數據流入

epoll_ctl(epollfd, EPOLL_CTL_DEL, socket, EPOLLOUT);//注冊緩沖區非滿事件,即流可以被寫入

epoll_wait(epollfd,...)等待直到注冊的事件發生

(注:當對一個非阻塞流的讀寫發生緩沖區滿或緩沖區空,write/read會返回-1,并設置errno=EAGAIN。而epoll只關心緩沖區非滿和緩沖區非空事件)。

?

對于第一個缺點,epoll的解決方案在epoll_ctl函數中。每次注冊新的事件到epoll句柄中時(在epoll_ctl中指定EPOLL_CTL_ADD),會把所有的fd拷貝進內核,而不是在epoll_wait的時候重復拷貝。epoll保證了每個fd在整個過程中只會拷貝一次。

?

對于第二個缺點,epoll的解決方案不像select或poll一樣每次都把current輪流加入fd對應的設備等待隊列中,而只在epoll_ctl時把current掛一遍(這一遍必不可少)并為每個fd指定一個回調函數,當設備就緒,喚醒等待隊列上的等待者時,就會調用這個回調函數,而這個回調函數會把就緒的fd加入一個就緒鏈表。epoll_wait的工作實際上就是在這個就緒鏈表中查看有沒有就緒的fd(利用schedule_timeout()實現睡一會,判斷一會的效果,和select實現中的第7步是類似的)。

?

對于第三個缺點,epoll沒有這個限制,它所支持的FD上限是最大可以打開文件的數目,這個數字一般遠大于2048,舉個例子,在1GB內存的機器上大約是10萬左右,具體數目可以cat /proc/sys/fs/file-max察看,一般來說這個數目和系統內存關系很大。

?

總結:

1)select,poll實現需要自己不斷輪詢所有fd集合,直到設備就緒,期間可能要睡眠和喚醒多次交替。而epoll其實也需要調用epoll_wait不斷輪詢就緒鏈表,期間也可能多次睡眠和喚醒交替,但是它是設備就緒時,調用回調函數,把就緒fd放入就緒鏈表中,并喚醒在epoll_wait中進入睡眠的進程。雖然都要睡眠和交替,但是select和poll在“醒著”的時候要遍歷整個fd集合,而epoll在“醒著”的時候只要判斷一下就緒鏈表是否為空就行了,這節省了大量的CPU時間。這就是回調機制帶來的性能提升。

2)select,poll每次調用都要把fd集合從用戶態往內核態拷貝一次,并且要把current往設備等待隊列中掛一次,而epoll只要一次拷貝,而且把current往等待隊列上掛也只掛一次(在epoll_wait的開始,注意這里的等待隊列并不是設備等待隊列,只是一個epoll內部定義的等待隊列)。這也能節省不少的開銷。

?

epoll原理

  • epoll初始化時,會向內核注冊一個文件系統,用于存儲被監控的句柄文件,調用epoll_create時,會在這個文件系統中創建一個file節點。同時epoll會開辟自己的內核高速緩存區,以紅黑樹的結構保存句柄,以支持快速的查找、插入、刪除。還會再建立一個list鏈表,用于存儲準備就緒的事件。
  • 當執行epoll_ctl時,除了把socket句柄放到epoll文件系統里file對象對應的紅黑樹上之外,還會給內核中斷處理程序注冊一個回調函數,告訴內核,如果這個句柄的中斷到了,就把它放到準備就緒list鏈表里。所以,當一個socket上有數據到了,內核在把網卡上的數據copy到內核中后,就把socket插入到就緒鏈表里。
  • 當epoll_wait調用時,僅僅觀察就緒鏈表里有沒有數據,如果有數據就返回,否則就sleep,超時時立刻返回。
  • 邊緣觸發模式ET(Edge_triggered)和水平觸發模式LT(Level_triggered)

    Level_triggered(水平觸發):當被監控的文件描述符上有可讀寫事件發生時,epoll_wait()會通知處理程序去讀寫。如果這次沒有把數據一次性全部讀寫完(如讀寫緩沖區太小),那么下次調用 epoll_wait()時,它還會通知你在上沒讀寫完的文件描述符上繼續讀寫,當然如果你一直不去讀寫,它會一直通知你!!!如果系統中有大量你不需要讀寫的就緒文件描述符,而它們每次都會返回,這樣會大大降低處理程序檢索自己關心的就緒文件描述符的效率!!!

    ?

    Edge_triggered(邊緣觸發):當被監控的文件描述符上有可讀寫事件發生時,epoll_wait()會通知處理程序去讀寫。如果這次沒有把數據全部讀寫完(如讀寫緩沖區太小),那么下次調用epoll_wait()時,它不會通知你,也就是它只會通知你一次,直到該文件描述符上出現第二次可讀寫事件才會通知你!!!這種模式比水平觸發效率高,系統不會充斥大量你不關心的就緒文件描述符!!!

    ?

    IOCP(AIO)

    微軟在 Winsocket2 中引入了 IOCP(Input/Output Completion Port)模型。IOCP 是 Input/Output Completion Port(I/O 完成端口)的簡稱。簡單的說,IOCP 是一種高性能的 I/O 模型,是一種應用程序使用線程池處理異步 I/O 請求的機制。Java7 中對 IOCP 有了很好的封裝,程序員可以非常方便的時候經過封裝的 channel 類來讀寫和傳輸數據。

    不僅和epoll一樣接收到Socket的事件,并且接收時OS已經完成了IO,不需要在應用層進行IO。

    ?

    首先我們創建一個完成端口 CreateIOCompletionPort,然后再創建一個或多個工作線程,并指定它們到這個完成端口上去讀取數據。再將遠程連接的套接字句柄關聯到這個完成端口。工作線程調用 getQueuedCompletionStatus 方法在關聯到這個完成端口上的所有套接字上等待 I/O 的完成,再判斷完成了什么類型的 I/O,然后接著發出 WSASend 和 WSARecv,并繼續下一次循環阻塞在 getQueuedCompletionStatus。

    ?

    具體的說,一個完成端口大概的處理流程包括:

    ?

    創建一個完成端口;

    Port port = createIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, fixedThreadCount());

    創建一個線程 ThreadA;

    ThreadA 線程循環調用 GetQueuedCompletionStatus 方法來得到 I/O 操作結果,這個方法是一個阻塞方法;

    ?While(true){

    ?????? ?getQueuedCompletionStatus(port, ioResult);

    ?}

    主線程循環調用 accept 等待客戶端連接上來;

    主線程 accept 返回新連接建立以后,把這個新的套接字句柄用 CreateIoCompletionPort 關聯到完成端口,然后發出一個異步的 Read 或者 Write 調用,因為是異步函數,Read/Write 會馬上返回,實際的發送或者接收數據的操作由操作系統去做。

    ?if (handle != 0L) {

    ?????? ?createIoCompletionPort(handle, port, key, 0);

    ?}

    主線程繼續下一次循環,阻塞在 accept 這里等待客戶端連接。

    操作系統完成 Read 或者 Write 的操作,把結果發到完成端口。

    ThreadA 線程里的 GetQueuedCompletionStatus() 馬上返回,并從完成端口取得剛完成的 Read/Write 的結果。

    在 ThreadA 線程里對這些數據進行處理 ( 如果處理過程很耗時,需要新開線程處理 ),然后接著發出 Read/Write,并繼續下一次循環阻塞在 GetQueuedCompletionStatus() 這里。

    ?

    分區

    磁盤的文件名

    Linux 中每個硬件都被當做一個文件。

    常見磁盤的文件名:

    SCSI/SATA/USB 磁盤:/dev/sd[a-p]

    IDE 磁盤:/dev/hd[a-d]

    其中文件名后面的序號的確定與磁盤插入的順序有關,而與磁盤所插入的插槽位置無關。

    Linux系統使用字母和數字的組合來指代硬盤分區,Linux系統使用一種更加靈活的命名方案,該命名方案是基于文件的,文件名的格式為/dev/xxyN,

    /dev/:這是Linux系統下所有設備文件所在的目錄名。

    xx:分區名的前兩個字母表示分區所在設備的類型,通常是hd(IDE硬盤)或sd(SCSI硬盤)。

    y:這個字母表示分區所在的設備。

    N:最后的數字N代表分區。

    掛載目錄:

    Linux系統處理分區及磁盤存儲的方法與Windows截然不同,Linux系統中的每一個分區都是構成支持一組文件和目錄所必需的存儲區的一部分。它是通過掛載來實現的,掛載是將分區關聯到某一目錄的過程,掛載分區使起始于這個指定目錄(通稱為掛載目錄)的存儲區能夠被使用。

    分區表

    磁盤分區表主要有兩種格式,一種是限制較多的 MBR 分區表,一種是較新且限制較少的 GPT 分區表。

    ?

    1. MBR

    MBR 中,第一個扇區最重要,里面有:主要開機記錄(Master boot record, MBR)及分區表(partition table),其中 MBR 占 446 bytes,partition table 占 64 bytes。

    ?

    分區表只有 64 bytes,最多只能存儲 4 個分區,這 4 個分區為主分區(Primary)和擴展分區(Extended)。其中擴展分區只有一個,它將其它空間用來記錄分區表,可以記錄更多的分區,因此通過擴展分區可以分出更多區分,這些分區稱為邏輯分區。

    ?

    Linux 也把分區當成文件,分區文件的命名方式為:磁盤文件名+編號,例如 /dev/sda1。注意,邏輯分區的編號從 5 開始。

    ?

    2. GPT

    不同的磁盤有不同的扇區大小,例如 512bytes 和最新磁盤的 4k。GPT 為了兼容所有磁盤,在定義扇區上使用邏輯區塊地址(Logical Block Address, LBA)。

    ?

    GPT 第 1 個區塊記錄了 MBR,緊接著是 33 個區塊記錄分區信息,并把最后的 33 個區塊用于對分區信息進行備份。

    壓縮

    tar [主選項+輔選項][文件或者目錄]

    ?

    備份/root/abc目錄及其子目錄下的全部文件,備份文件名為abc.tar。

    [root@PC-LINUX ~]# touch /root/abc/a /root/abc/b /root/abc/c

    //在/root/abc目錄中創建/root/abc/a、/root/abc/b和/root/abc/c文件

    [root@PC-LINUX ~]# tar cvf abc.tar /root/abc

    ?

    查看abc.tar備份文件的內容,并顯示在顯示器上。

    [root@PC-LINUX ~]# tar tvf abc.tar

    ?

    將文件/root/abc/d添加到abc.tar包里面去。

    [root@PC-LINUX ~]# touch /root/abc/d

    [root@PC-LINUX ~]# tar rvf abc.tar /root/abc/d

    ?

    更新原來tar包abc.tar中的文件/root/abc/d。

    [root@PC-LINUX ~]# tar uvf abc.tar /root/abc/d

    ?

    tar調用gzip

    把/root/abc目錄包括其子目錄全部做備份文件,并進行壓縮,文件名abc.tar.gz。

    [root@PC-LINUX ~]# tar zcvf abc.tar.gz /root/abc

    ?

    查看壓縮文件abc.tar.gz的內容,并顯示在顯示器上。

    [root@PC-LINUX ~]# tar ztvf abc.tar.gz

    ?

    將壓縮文件abc.tar.gz解壓縮出來。

    [root@PC-LINUX ~]# tar zxvf abc.tar.gz

    ?

    tar調用bzip2

    將目錄/root/abc及該目錄所有文件壓縮成abc.tar.bz2文件。

    [root@PC-LINUX ~]# tar cjf abc.tar.bz2 /root/abc

    ?

    查看壓縮文件abc.tar.bz2的內容,并顯示在顯示器上。

    [root@PC-LINUX ~]# tar tjf abc.tar.bz2

    ?

    將abc.tar.bz2文件解壓縮。

    [root@PC-LINUX ~]# tar xjf abc.tar.bz2

    ?

    總結

    以上是生活随笔為你收集整理的Linux必懂知识大总结(下)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。