Monday, January 3, 2022

[Linux Kernel] 進程上下文與中斷上下文

 程序在執行過程中通常有用戶態和內核態兩種狀態,CPU對處于內核態根據上下文環境進一步細分,因此有了下面三種狀態:

(1)內核態,運行于進程上下文,內核代表進程運行于內核空間。 Process context

(2)內核態,運行于中斷上下文,內核代表硬件運行于內核空間 。Interrupt context 

(3)用戶態,運行于用戶空間。

进程切换

为了控制进程的执行,内核必须有能力挂起正在CPU上运行的进程,并恢复以前挂起的某个进程的执行。这种行为被称为进程切换。因此可以说,任何进程都是在操作系统内核的支持下运行的,是与内核紧密相关的。

从一个进程的运行转到另一个进程上运行,这个过程中经过下面这些变化:
1. 保存处理机上下文,包括程序计数器和其他寄存器。
2. 更新PCB信息。
3. 把进程的PCB移入相应的队列,如就绪、在某事件阻塞等队列。
4. 选择另一个进程执行,并更新其PCB。
5. 更新内存管理的数据结构。
6. 恢复处理机上下文。

注:总而言之就是很耗资源,具体的可以参考这篇文章:进程切换

用戶空間的應用程序,通過系統調用,進入內核空間。這個時候用戶空間的進程要傳遞 很多變量、參數的值給內核,內核態運行的時候也要保存用戶進程的一些寄存 器值、變量等。

另外,前面提到 kernel space「不能被 preempt」,但只要啟動 kernel 配置選項的「CONFIG_PREEMPT」,kernel space 也會變成可以被 preempt。


所謂的“進程上下文”,可以看作是用戶進程傳遞給內核的這些參數以及內核要保存的那一整套的變量和寄存器值和當時的環境等

一個進程的上下文可以分為三個部分:

用戶級上下文

寄存器上下文

系統級上下文

(1)用戶級上下文: 正文、數據、用戶堆棧以及共享存儲區;

(2)寄存器上下文: 通用寄存器、程序寄存器(IP)、處理器狀態寄存器(EFLAGS)、棧指針(ESP);

(3)系統級上下文: 進程控制塊task_struct、內存管理信息(mm_struct、vm_area_struct、pgd、pte)、內核棧。

當發生進程調度時,進行進程切換就是上下文切換(context switch).操作系統必須對上面提到的全部信息進行切換,新調度的進程才能運行。而系統調用進行的模式切換(mode switch)。模式切換與進程切換比較起來,容易很多,而且節省時間,因為模式切換最主要的任務只是切換進程寄存器上下文的切換。

硬件通過觸發信號,導致內核調用中斷處理程序,進入內核空間。這個過程中,硬件的 一些變量和參數也要傳遞給內核,內核通過這些參數進行中斷處理。

所謂的“ 中斷上下文”,其實也可以看作就是硬件傳遞過來的這些參數和內核需要保存的一些其他環境(主要是當前被打斷執行的進程環境)。中斷時,內核不代表任何進程運行,它一般只訪問系統空間,而不會訪問進程空間,內核在中斷上下文中執行時一般不會阻塞

[Linux Kernel] linux驅動面試題目彙總及解答

linux 驅動分類

Linux裝置驅動的分類 

(1)字元裝置

       不定長度的字元傳送資料 /dev/console

(2) 塊裝置

        固定大小長度來傳送轉移資料

        可以隨機存取 (Random Access) 資料的設備,如硬碟機或光碟機

(3) 網路裝置

自旋鎖

防止多處理器併發而引入的一種鎖,它應用於中斷處理等部分

對於單處理器來說,防止中斷處理中的併發可簡單採用關閉中斷的方式,不需要自旋鎖

自旋鎖最多只能被一個核心任務持有,如果一個核心任務試圖請求一個已被爭用(已經被持有)的自旋鎖,那麼這個任務就會一直進行忙迴圈——旋轉——等待鎖重新可用。要是鎖未被爭用,請求它的核心任務便能立刻得到它並且繼續進行。

自旋鎖可以在任何時刻防止多於一個的核心任務同時進入臨界區,防止核心搶佔造成的競爭。因此這種鎖可有效地避免多處理器上併發執行的核心任務競爭共享資源。

事實上,自旋鎖的初衷就是:在短期間內進行輕量級的鎖定。一個被爭用的自旋鎖使得請求它的執行緒在等待鎖重新可用的期間進行自旋(特別浪費處理器時間),所以自旋鎖不應該被持有時間過長。如果需要長時間鎖定的話, 最好使用訊號量。但是自旋鎖節省了上下文切換的開銷。

自旋鎖的基本形式如下:

spin_lock(&mr_lock);


//臨界區

spin_unlock(&mr_lock);

另外自旋鎖不允許任務睡眠(持有自旋鎖的任務睡眠會造成自死鎖——因為睡眠有可能造成持有鎖的核心任務被重新排程,而再次申請自己已持有的鎖),它能夠在中斷上下文中使用。

死鎖

所有核心任務都在相互等待,但它們永遠不會釋放已經佔有的資源

訊號量

訊號量是一種睡眠鎖。如果有一個任務試圖獲得一個已被持有的訊號量時,訊號量會將其推入等待佇列,然後讓其睡眠。這時處理器獲得自由去執行其它程式碼。當持有訊號量的程序將訊號量釋放後,在等待佇列中的一個任務將被喚醒,從而便可以獲得這個訊號量。

訊號量的睡眠特性,使得訊號量適用於鎖會被長時間持有的情況;只能在程序上下文中使用,因為中斷上下文中是不能被排程的;另外當代碼持有訊號量時,不可以再持有自旋鎖。

訊號量基本使用形式為:

static DECLARE_MUTEX(mr_sem);//宣告互斥訊號量

if(down_interruptible(&mr_sem))

           //可被中斷的睡眠,當訊號來到,睡眠的任務被喚醒

           //臨界區

       up(&mr_sem); 

訊號量和自旋鎖區別

如果需要在自旋鎖和訊號量中作選擇,應該取決於鎖被持有的時間長短。

理想情況是所有的鎖都應該儘可能短的被持有,但是如果鎖的持有時間較長的話,使用訊號量是更好的選擇。

另外,訊號量不同於自旋鎖,它不會關閉核心搶佔,所以持有訊號量的程式碼可以被搶佔。這意味者訊號量不會對影響排程反應時間帶來負面影響。

1. 低開銷加鎖 優先使用自旋鎖

2. 短期鎖定 優先使用自旋鎖

3. 長期加鎖 優先使用訊號量

4. 中斷上下文中加鎖 使用自旋鎖

5. 持有鎖是需要睡眠、排程 使用訊號量 

kmalloc()和vmalloc()介紹

kmalloc()

用於申請較小的、連續的實體記憶體

1. 以位元組為單位進行分配,在<linux/slab.h>中

2. void *kmalloc(size_t size, int flags) 分配的記憶體實體地址上連續,虛擬地址上自然連續

3. gfp_mask標誌:什麼時候使用哪種標誌?如下:

———————————————————————————————-

情形 相應標誌

———————————————————————————————-

程序上下文,可以睡眠 GFP_KERNEL

程序上下文,不可以睡眠 GFP_ATOMIC

中斷處理程式 GFP_ATOMIC

軟中斷 GFP_ATOMIC

Tasklet GFP_ATOMIC

用於DMA的記憶體,可以睡眠 GFP_DMA | GFP_KERNEL

用於DMA的記憶體,不可以睡眠 GFP_DMA | GFP_ATOMIC

4. void kfree(const void *ptr)

釋放由kmalloc()分配出來的記憶體塊

vmalloc()

用於申請較大的記憶體空間,虛擬記憶體是連續的

1. 以位元組為單位進行分配,在<linux/vmalloc.h>中

2. void *vmalloc(unsigned long size) 分配的記憶體虛擬地址上連續,實體地址不連續

3. 一般情況下,只有硬體裝置才需要實體地址連續的記憶體,因為硬體裝置往往存在於MMU之外,根本不瞭解虛擬地址;但為了效能上的考慮,核心中一般使用 kmalloc(),而只有在需要獲得大塊記憶體時才使用vmalloc(),例如當模組被動態載入到核心當中時,就把模組裝載到由vmalloc()分配 的記憶體上。

4.void vfree(void *addr),這個函式可以睡眠,因此不能從中斷上下文呼叫。

malloc(), vmalloc()和kmalloc()區別

[*]kmalloc和vmalloc是分配的是核心的記憶體,malloc分配的是使用者的記憶體

[*]kmalloc保證分配的記憶體在物理上是連續的,vmalloc保證的是在虛擬地址空間上的連續,malloc不保證任何東西(這點是自己猜測的,不一定正確)

[*]kmalloc能分配的大小有限,vmalloc和malloc能分配的大小相對較大

[*]記憶體只有在要被DMA訪問的時候才需要物理上連續

[*]vmalloc比kmalloc要慢

Sunday, January 2, 2022

[靜態檢查工具] index

 1、KLOCWORK:

適用語言:C, C++, JAVA

是否開源:否,

是否需要編譯:是

作用:程式碼靜態檢查工具。用於高效檢測軟體缺陷和安全隱患,提供優秀的靜態原始碼分析解決方案。軟體號稱是業界領導者,能夠快速、準確分析大規模(幾百萬,甚至幾千萬行)、高複雜度程式碼的工具。能夠自動化檢測和解決C/C++、Java等原始碼中的嚴重、安全和規範類的缺陷。通過對構建環境、原始碼和開發過程給出一個完整的分析,最終實現高質量軟體。


2、COVERITY:

適用語言:C, C++, JAVA,PYTHON,java scrip

是否開源:否,

是否需要編譯:是

作用:用於高效檢測軟體缺陷和安全隱患,提供優秀的靜態原始碼分析解決方案。軟體號稱是業界領導者,是第一個能夠快速、準確分析大規模(幾百萬,甚至幾千萬行)、高複雜度程式碼的工具。內部採用Prevent SQS(軟體質量系統)架構方法,能夠自動化檢測和解決C/C++、Java等原始碼中的嚴重缺陷。通過對構建環境、原始碼和開發過程給出一個完整的分析,最終實現高質量軟體。

Reference:

https://www.itread01.com/content/1546712855.html

3、FORTIFY:

適用語言:C, C++, JAVA,PYTHON,java scrip

 是否開源:否,

是否需要編譯:是

作用:程式碼安全測試工具。它通過內建的五大主要分析引擎:資料流、語義、結構、控制流、配置流等對應用軟體的原始碼進行靜態的分析,分析的過程中與它特有的軟體安全漏洞規則集進行全面地匹配、查詢,從而將原始碼中存在的安全漏洞掃描出來,並給予整理報告。

4、CPPTEST:


適用語言:C, C++

 是否開源:否,

是否需要編譯:是

作用:Parasoft ®  C/C++test  TM –針對 C/C++ 開發的綜合性程式碼質量保障工具,使用C++test經時間驗證的重要最佳實踐—例如靜態分析,全面的程式碼審查,執行時錯誤檢測,整合覆蓋率分析的單元測試和元件測試—能夠在開發週期的開始階段,自動地在開發者的桌面上完成。能夠通過命令列模式自動化地執行迴歸和持續整合測試,為監測和分析質量趨勢提供資料。

5、TOX

適用語言:PYTHON

是否開源:是

是否需要編譯:否

 作用:TOX是一個通用的virtualenv管理和測試命令列工具,TOX的目標是提供最先進的自動化打包,測試和釋出的Python軟體的工具,可以用於控制檯或者基礎到你的持續構建平臺。

支援功能:

                 1)、檢查你的包被正確地安裝不同版本的Python和解析器

                 2)、在每個環境中執行你的測試,配置測試工具的選擇

                 3)、作為一個持續整合伺服器的前端,大大降低了測試工作量。


6、Flake8

適用語言:PYTHON

是否開源:是

是否需要編譯:否

作用:Flake8是Python程式碼規範利器,他封裝了三個工具:1)PyFlakes:靜態檢查Python程式碼邏輯錯誤的工具;2)pep8: 靜態檢查PEP 8編碼風格的工具;3)Ned Batchelder’s McCabe script:靜態分析Python程式碼複雜度的工具。flake8綜合了上述三個工具的功能,還提供了擴充套件開發介面。

主要特徵:

1)包含這行檔案將被忽略:#flake8: noqa

2)結尾包含#noqa註釋的行將不釋出告警

3)GIT和Mercurial鉤子

4)McCabe複雜度檢查器

5)可以通過flake8.extension入口點擴充套件

Flake8的下載地址:https://pypi.python.org/pypi/flake8

7、GO LINT:

適用語言:GO

是否開源:是

是否需要編譯:否

作用:編碼規範類檢查

8、GO VET:

適用語言:GO

是否開源:是

是否需要編譯:否

作用:檢查原始碼並報告可疑結構

9、SONAR:

適用語言:C, C++, JAVA,PYTHON,java scrip

是否開源:是

是否需要編譯:否

作用:Sonar (SonarQube)是一個開源平臺,用於管理原始碼的質量。Sonar 不只是一個質量資料報告工具,更是程式碼質量管理平臺。支援的語言包括:Java、PHP、C#、C、Cobol、PL/SQL、Flex 等。

開源中國程式碼質量管理系統 -> http://sonar.oschina.net/

主要特點:

 •程式碼覆蓋:通過單元測試,將會顯示哪行程式碼被選中

 •改善編碼規則

 •搜尋編碼規則:按照名字,外掛,啟用級別和類別進行查詢

 •專案搜尋:按照專案的名字進行查詢

 •對比資料:比較同一張表中的任何測量的趨勢

10、Scalastyle:

  適用語言:Scala

是否開源:是

是否需要編譯:否

作用:Scalastyle是個簡單易用的code style檢測工具,非常輕巧,有助於團隊風格一致。

1)目前有63條規則,主要集中在程式碼格式,如檔案行數、方法行數是否過多,是否指定了返回值,圈複雜度是否高於閾值等

2)有些規則和使用習慣不一致,如檔案首必須有license說明,if後必須有花括號等;

3)使用很簡單,一個配置,一行命令就可以,參見http://www.scalastyle.org/sbt.html

4)可以和CI結合

 建議:因為側重格式方面,因此可以有條件使用,即關閉若干與習慣嚴重不符的規則,配合另外的能夠做安全檢查的工具;

[Other] 小内存处理1G或10G大小的log文件

 主要原理:大文件分割成小文件。split 分割文件命令


为了保证文件的完整性,要按行分割

wc -l test.log   #查看总共多少行

可知81910500行, 分割成10M左右,81910500/102.4 约800000 行一个文件

#     按行  行数   文件名   后缀数字  后缀4位   前缀  

split -l 800000 test.log -d       -a   4   test_




查看小文件即可

less test_0001

cat -n test_0001 | grep 查找内容



补充内容:

1、快速生成1G大log文件

首先我有约100k的小文件s.log,循环 10500次生成大约1G文件test.log。

shell脚本内容如下:


touch test.log

 

for((i=0;i<10500;i++))

do

    cat s.log >> test.log

    echo "www.djlcx.cn" >>test.log

done


2、split的使用

-b 按文件大小分割

split -b 1M file      #默认后缀是字母 xaa xab xac ...

split -b 10k file -d -a 3   #3位数字后缀  x000 x001 x002 ...

split -b 10k file -d -a 3 split_   #指定前缀



3、合并文件

cat test_* >t.log

————————————————

原文链接:https://blog.csdn.net/u010071211/article/details/85166744

Other Index

Blockchain

Docker

tmux

Kubernetes

平行壓縮程式

other

win10连接无线时不能输入密码

語系代碼 ISO 639-1

小内存处理1G或10G大小的log文件

Google Style Guide

  一个辅助 Clang-Format 整个目录的简单工具

 Clang-format格式化及配置参数

Friday, December 31, 2021

[python 反爬蟲原理與繞過實戰] 第三方庫安裝

Requests (http 請求庫)

pip install requests

Selenium (web 應用程序測試工具)

pip install selenium

瀏覽器驅動

ChromeDriver

查詢版本 

版本 1.33.106 Chromium: 96.0.4664.110 (正式版本) (64 位元)

下載並執行

sudo mv chromedriver /usr/bin/

Firefox
geckodriver --version

Splash 異步 JavaScript 渲染服務

從 dockerHub 中拉取 Splash

sudo docker run -it -p 8050:8050 scrapinghub/splash

http://localhost:8050

Puppeteer (Google 出的 Node.js 庫)

pip install pyppeteer


安裝

https://ithelp.ithome.com.tw/articles/10233316

https://github.com/tesseract-ocr/tesseract

https://officeguide.cc/tesseract-open-source-ocr-engine-tutorial-examples/






cuDNN (深度神經網路庫)

[python 反爬蟲原理與繞過實戰] 安裝 docker

安裝 docker (參考)

sudo apt-get update

1. 安裝允許 apt 通過 https 協議使用存儲庫

sudo apt-get install apt-transport-https

sudo apt-get install ca-certificates

sudo apt-get install curl

sudo apt-get install gnupg-agent

sudo apt-get install software-properties-common

2. 添加 docker 官方的 gpg 密鑰

sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

確認密鑰添加成功

abc@ubuntu:/extspace/src$ sudo apt-key fingerprint 0EBFCD88

pub   rsa4096 2017-02-22 [SCEA]

      9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88

uid           [ unknown] Docker Release (CE deb) <docker@docker.com>

sub   rsa4096 2017-02-22 [S]

添加 Stable 版本的存儲庫

sudo add-apt-repository "deb [arch=$(dpkg --print-architecture)] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

or 

echo \

  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \

  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

安裝 Docker CE

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

確認

abc@ubuntu:/extspace/src$ sudo docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

n8n index

 【n8n免費本地端部署】Windows版|程式安裝x指令大補帖  【一鍵安裝 n8n】圖文教學,獲得無限額度自動化工具&限時免費升級企業版功能