Linux相關概念和易錯知識點(25)(信號原理、操作系統的原理、volatile)

目錄

1.信號的產生

(1)kill

(2)raise、abort

2.對block、pending、handler表的管理

(1)信號集(sigset_t)

(2)block表的管理

①操作相關的函數

②sigprocmask

(3)pending表的管理

(4)handler表的管理

3.操作系統的原理

(1)硬件中斷

①中斷控制器

②中斷號

③保護現場、恢復現場

(2)時鐘源

①主頻

②時間片

(3)異常處理

(4)軟中斷

①軟中斷和硬件中斷

②系統調用表

③缺頁中斷

④異常、陷阱

(5)用戶態和內核態(重點)

①用戶區、內核區

②用戶態和內核態之間的切換

③函數跳轉

(6)捕捉信號流程

①用戶態和內核態的切換

②對狀態切換的理解

③對執行流概念的深化

(7)volatile

①可重入函數

②volatile、編譯器優化

4.信號拓展

(1)SIGCHLD

(2)SIGALRM


1.信號的產生

(1)kill

信號究竟是如何產生的?我們已經知道信號的各種上層規則,但對于信號的來源還不是很熟悉。

看一下下面的代碼,就能很快理解了。

kill本身就是個系統調用,而不僅僅是一個指令int kill(pid_t pid, int sig);就可以實現對特定的pid進程發送sig信號,當信號發送成功時返回0,失敗時返回-1。

也就是說所謂的kill指令,底層還是kill函數系統調用(指令->系統調用)。因此我們可以理解,當bash進程要kill掉其子進程時,就是調用的kill函數實現的。如當管道的讀端關閉,系統會直接殺掉進程,就是使用的kill發送SIGPIPE信號

(2)raise、abort

int raise( int )意思是誰調用,就給自己發送這個信號,也就是說raise(9)可以殺掉自己。

void abort( void )意思是誰調用,就給自己發送SIGABRT 6號終止信號。相當于raise(6)

2.對block、pending、handler表的管理

在介紹了三張表的功能和調用流程之后,我們需要進一步講講如何修改這三張表,因為信號從接收到發送的全過程都由這三張表控制,管理這三張表本質上就是在管理信號的處理。

(1)信號集(sigset_t)

未決(pending)和阻塞(block)表都可用相同類型來存儲,因為它們本質都是位圖。這個位圖的結構體是sigsei_t,也稱為信號集這個類型在兩張表有不同含義:在pending表表示是否有接收到該信號,在block表表示是否阻塞該信號阻塞(block)信號集也叫做當前進程的信號屏蔽字(Signal Mask),這里的屏蔽是指阻塞。

我們只需記住信號集的本質是位圖,是未決(pending)和阻塞(block)表中位圖的專屬類型。?

(2)block表的管理

注意以下的函數都是針對block表的信號集!

①操作相關的函數

首先,我們需要自己創建一個sigset_t的變量,再對這個位圖進行如下處理:

int sigemptyset(sigset_t *set);將位圖清0;?int sigfillset(sigset_t *set);將位圖填為全1

int sigaddset(sigset_t *set, int signum);添加對signum號信號的屏蔽(本質就是修改位圖,將對應位改為1);int sigdelset(sigset_t *set, int signum);刪除對signum號信號的屏蔽

上述返回值都是0為成功,-1為錯誤

②sigprocmask

接下來我們要讓我們的改動生效,上述所有的改動都是用戶自己的修改,并沒有寫到內核中去。

int sigprocmask(int how, const sigset_t *newset, sigset_t *oldset);

how由如下宏定義決定功能:SIG_BLOCK增加傳入的newset中狀態為1的信號的阻塞;SIG_UNBLOCK解除傳入的newset中狀態為1的信號的阻塞;SIG_SETMASK直接用newset覆蓋block表中的位圖。注意這個newset就是剛才我們進行各種處理后的sigset_t變量(輸入型參數)。oldset是輸出型參數,是修改前的位圖,幫助我們恢復原來的位圖。

除了上述用法之外,sigprocmask(0, NULL, &oldset)可以獲取當前的block表

下面的代碼,我利用阻塞表阻塞了2號信號的處理,使得信號無法被處理

(3)pending表的管理

int sigpending(sigset_t *set);用于獲取pending表,set是一個輸出型參數,該函數只提供內核中的pending表而不提供修改。其返回值0表示成功,-1表示失敗。

int sigismember(const sigset_t *set, int signum);?判斷signum對應信號是否有效。pending和block表都可以用,因為它們的位圖的數據類型一致。我們需要手動傳入sigset_t,這需要我們使用sigpromask、sigpending獲取當前block、pending表。其返回值是1為真,0為假,-1為錯誤

(4)handler表的管理

signal函數可以進行信號捕捉,進而修改handler表,這里提一句即可。

int sigaction(int signum, const struct sigaction* newact, struct sigaction* oldact);

對于這個結構體,通常flag設置為0,sa_handler設置為指定的void(int)函數指針,使用為sigaction(2, &act, &oldact),即將信號2的默認處理方式替換為自定義處理,并且得到一個oldact用于備份。

struct sigaction的sa_mask成員還可以順便幫我們添加要屏蔽的信號,我們自己設置sigset_t,在后續調用sigaction函數時,除了相應pending表被修改,block表也會加上sa_mask里面的幾個屏蔽的信號。

3.操作系統的原理

要進一步理解信號,我們要對OS進一步深挖,來解釋為什么我們鍵盤輸入信號后OS能夠及時的處理?是否需要OS一直等待鍵盤輸入?同步異步是如何實現的?

(1)硬件中斷

OS怎么知道鍵盤輸入數據了?是否需要OS一直等待鍵盤輸入?事實上,OS是啟動的第一個軟件,它不會輪詢設備,設備數量太多了,鍵盤、磁盤、顯示屏等,而是外設提醒OS后OS再來處理。

①中斷控制器

以鍵盤輸入為例,鍵盤按下會首先觸發硬件中斷(由硬件電路實現),這個硬件中斷的信號不會直接傳給CPU(物理上鍵盤并沒有直連CPU),而是傳給中斷控制器(和每個設備直連),中斷控制器再向CPU發送信息,進而被OS獲取。

注意中斷控制器可不會關心鍵盤按什么鍵,它只會告訴CPU發生了中斷,CPU也不會關心,它收到中斷后只會告訴OS有外設準備好了,之后在OS的管理下,鍵盤給CPU傳信息,進而實現給OS傳信息。至于鍵盤輸入了什么,那是OS之后需要干的事

再以磁盤為例,當磁盤想要給進程發信息時,雖然磁盤的尋址需要時間,要定位要準備,但這段時間OS不管,繼續執行自己的任務,僅當磁盤準備好后中斷控制器直接向CPU發送信號,執行讀取操作即可。這樣,硬件和OS實現了并行執行。

這里我們就會發現,信號和硬件中斷有相似之處,信號是純軟件模擬中斷的行為,硬件中斷是靠軟硬結合實現的(絕大部分是硬件)。

②中斷號

對于中斷控制器而言,每個設備都對應一個中斷號,中斷控制器利用中斷號觸發高電平告訴CPU誰中斷了。這些中斷號OS明白對應哪些設備,此時OS就回去調用對應的處理方法。要管理這些處理方法,OS有一個中斷向量表IDT,這是一個函數指針數組,中斷號就相當于數組下標。當中斷控制器告訴OS中斷號后,OS直接由IDT調用中斷服務處理中斷。這些中斷服務包括讀取硬盤、網卡等。方法內容由OS自定或安裝驅動確定,同時我們也要知道中斷號和中斷處理方法是相對固定的,是軟硬結合共同維護的。

③保護現場、恢復現場

在OS接收到中斷控制器的信號,確定要處理中斷之后,OS會將當前CPU各種寄存器的數據保存在中斷的上下文,方便后續處理。保存好寄存器數據后,OS就會根據中斷向量表找方法,執行中斷處理例程(利用中斷號查表)。處理完后就會恢復現場,繼續執行任務。

OS通過中斷實現了不主動輪詢外設。所有外設(不含內存,它是存儲器)都是這么處理的。

(2)時鐘源

進程可以在OS指揮下調度執行,那么OS自己被誰指揮呢?時鐘源。

①主頻

我們已經知道了所有外設的信息是如何進入進程被處理的了,其中有一個外設,每隔一段極短時間就會給CPU發硬件中斷,這個外設就是時鐘源,它具有一個固定的中斷號,以及一個固定的中斷服務:進程調度。時鐘源會一直推動OS進行進程調度,OS就是基于不斷中斷,調用中斷向量表工作的。現在時鐘源已經被集成在CPU內部,時鐘源的觸發頻率就是CPU主頻的概念(如14900K的6GHZ)。主頻速度越快,處理任何操作都會更頻繁。

OS在時鐘的推動下自行調度,相當于說OS可以不做任何事,啟動之后直接讓自己進入死循環,利用時鐘和其它外設觸發中斷推著它進行運行,執行方法。

總結:對于OS來說,只要完全沒有進程,它就陷在死循環中,但只要有進程,就會一直忙著調度,這是時鐘源的中斷推著它進行的。我們因此可以說操作系統就是躺在中斷中運行的。與此同時,OS也會自己去fork一些進程,這是內核固定進程,會定期去檢查OS運行狀態,定期把內核緩沖區數據進行刷新、檢查鬧鐘等操作。?

②時間片

時鐘中斷是固定時間的,假設為1ns。進程的調度都設置了時間片,輪詢著調度以盡量保持公平。OS要實現時間片,只需設置int count,當count == 1000(1微秒),每次時鐘源中斷觸發進程調度都會讓count--,count減到0后直接切換進程。

時間片就是在主頻下的計數器,是以時鐘中斷為基礎構建的。

(3)異常處理

我們已經知道,程序的崩潰就是靠信號終止的。

其中野指針觸發段錯誤,操作系統直接用11號信號殺掉進程,我們捕捉信號后發現OS一直在觸發信號。

同理,a / 0也會崩潰,會觸發13號信號SIGFPE終止進程。

為什么OS知道我們的進程的內部出錯了,為什么OS會一直觸發信號?

以a / 0為例,CPU中有寄存器,a -> eax,0 -> ebx, 計算結果 -> ecx。同時還有個狀態寄存器Eflags,有溢出標記位,默認為0,保證會把結果正常返回。當溢出標記位為1,OS就知道CPU硬件內部出錯了,OS找到對應的進程后就要用信號殺掉損壞CPU的進程。

當我們捕獲信號之后,我們的進程沒有退出,直到時間片到了,進行進程切換時會OS會保存寄存器數據,以便下次調用恢復。其中Eflags的標記位也被保存了,OS不會修改它。由此以來,每當調度到這個進程時,CPU都會顯示異常,OS會一直嘗試殺我們的進程,這導致了死循環調用信號處理。

同理,OS怎么判斷野指針呢?CR3寄存器保存頁表起始地址,虛擬?-> 物理地址的轉換是MMU內存管理單元操作的,它集成在CPU中。當訪問野指針(虛擬地址)時,MMU轉換去讀0,發現無法訪問,于是觸發了硬件錯誤,OS知道后發送信號嘗試殺掉進程。當后續再輪換調用時,MMU的錯誤被完整地繼承了下來,所以OS會循環發送信號。

(4)軟中斷

①軟中斷和硬件中斷

上述都是外部硬件中斷,需要硬件設備觸發。有沒有僅靠軟件進行中斷的呢?

為了讓OS支持系統調用,CPU專門設計了對應的匯編指令(int或者syscall),在沒有外設下,可以讓CPU內部觸發中斷邏輯。這些匯編指令就可以寫在軟件中,通過匯編指令 + 中斷號推動CPU執行中斷向量表方法,這就叫軟中斷。硬件中斷和軟中斷僅僅是觸發方式變為匯編調用,其余流程一致,這很好理解。

兩種觸發方式最終都是利用中斷號調用中斷向量表中的函數。例如,int N 指令會觸發中斷號為 N 的軟中斷,操作系統會根據該中斷號來找到對應的處理函數(范圍從 0x00 到 0xFF(即從 0 到 255))

②系統調用表

系統調用也是通過中斷完成的。OS系統調用都在系統調用表,集中管理,是由“下標”調用的。系統調用表特別底層且固定,用戶無法查看這個表的存在。這個表中各個函數的下標叫系統調用號,在中斷向量表中設置一個系統調用的入口函數,用系統調用號調用。

要調用系統調用,就要想辦法軟中斷,int 0x080就是軟中斷到執行系統調用入口函數,進入固定例程。系統調用號會提前寫到寄存器中,可以直接被獲取。

系統調用的過程:先把要調用的系統調用號用寄存器存起來,再觸發軟中斷陷入內核,OS根據中斷向量表開始進入中斷服務,根據寄存器里的系統調用號自動查系統調用表,執行對應方法。

OS提供的系統調用接口根本不是C函數,而是系統調用號 + 約定傳遞的參數,通過觸發軟中斷、進行中斷服務調用的方式實現系統調用功能的。系統調用的真正的底層實際上是匯編。

GNU、glibc給系統進行C語言封裝,給我們提供C語言的系統調用。所以我們用的所有系統調用都是C的,是它對該平臺的系統調用進行了統一的上層封裝,這也是C具有跨平臺性的本質。C語言的上層封裝還保證了我們系統調用的安全性,不會導致對系統造成傷害。

③缺頁中斷

缺頁異常意思就是有虛擬地址,但物理內存沒有申請(分批加載)。當OS需要用到相應空間,但發現還沒有物理內存時,就會觸發中斷,申請并加載物理內存

④異常、陷阱

OS就是躺在中斷例程上的代碼塊,幾乎所有操作都會轉為中斷。缺頁中斷、內存碎片處理、除零、野指針錯誤都是轉為軟中斷,OS會設置中斷號走中斷例程。異常、陷阱都會轉為軟中斷來處理。

如果發生了軟中斷且不是因為出錯,就是單純為了陷入中斷(系統調用),這叫做陷阱

而像除零、野指針這種觸發錯誤導致軟中斷的叫做異常。

OS會根據不同錯誤或者陷阱由中斷號進行調用。

(5)用戶態和內核態(重點)

①用戶區、內核區

在32位操作系統下,進程的地址空間劃分了4G,其中這塊虛擬的地址空間包含了我們已知的堆棧段、代碼段、數據段、以及命令行參數列表等。所有的這一切所在的內存區域都屬于用戶區。用戶區從0G ~ 3G,共3G的大小。

3G ~ 4G這塊叫做內核區,這塊內核區也是虛擬的,它擁有共同的內核頁表,同用戶頁表一樣,都是映射到物理內存中的。不過需要注意的是,不同進程的內核區都會映射到同一塊物理內存。

這里需要注意的是,用戶頁表每個進程一份,因為虛擬地址和物理地址都要根據不同進程實際情況映射。;而內核頁表則是整個系統一份,無論是虛擬地址還是映射的物理地址都是同一份。對于任何進程來說,無論如何調度,它們都能找到同一個OS,訪問同一張中斷向量表和系統調用表。

無論調用任何函數(庫、系統調用),都是在我們自己用戶區進行調用的(代碼段在用戶區)。而被調用的系統調用方法的執行是在內核區進行的。

本質上說,內核區映射到同一塊空間是因為OS只有一個,那么如果使得進程映射多塊空間,就相當于啟動了兩個系統,這就是內核虛擬機的思路,當然還有用戶虛擬機,這里提一句。

②用戶態和內核態之間的切換

前面我們已經知道用戶區和內核區了,這兩個區域只能被具有對應的身份的人訪問,標記身份的就是用戶態和內核態。

如果我們要進入內核區,我們需要將我們的身份進行改變,即用戶態 -> 內核態;同理,如果要訪問用戶區,我們也應該將內核態 -> 用戶態。?

標記用戶態和內核態的是CPU的CS段寄存器。它有兩個bit位的標志(CPL):00表示內核,11表示用戶。修改用戶內核態的本質就是修改標志位。我們都知道MMU是集成在CPU內部,負責進行虛擬地址 -> 物理地址的,只要CPL不允許訪問,MMU也自然不會給我們轉換地址,我們也自然訪問不了對應的空間。用戶態和內核態的權限管理是硬件層面的。

當我們在用戶區調用系統調用時,會使用int (中斷號) 和 syscall (中斷號) 觸發軟中斷,進到中斷向量表里面去執行系統調用入口函數,進而訪問系統調用表,執行系統調用方法,最后回到調用處繼續執行代碼。在整個過程中,當觸發軟中斷時就會第一次切換狀態,將權限標志位CPL改為0,進入內核態。執行完后返回調用處又會切換一次,CPL改為3,進入用戶態。

③函數跳轉

在上述流程中,我們會有疑問:函數是如何跳轉的,跳轉回來時如何找到最開始的地址的?A函數調用B,A會把調用B的下一個地址先入棧,后面出棧后就能夠找到下一句地址。由此以來就能正確地在內核區和用戶區之間進行跳轉。匯編層面所有操作都是基于寄存器、地址的。

(6)捕捉信號流程

有了前面知識的積累,我們能夠更底層地理解信號捕捉的流程了。

①用戶態和內核態的切換

如果來了一個信號,有可能當前進程正在做更重要的事,我們要把信號保存到pending表中。當進程從內核態切換回用戶態的時候,進程就會進行信號檢查do_signal(),檢測當前的pending和block表決定是否處理信號。

當要處理信號時,會根據不同處理信號的方式決定走向。如果是DFL和IGN的情況,那么進程會不急著返回用戶態,會在內核態把方法執行完成后再返回(DFL和IGN的代碼都在內核區);如果我們自定義捕捉了信號,這些代碼都在用戶區保存,所以我們要切換回用戶態執行處理代碼處理之后,會回到內核態,執行sys_sigreturn()返回主程序,回到用戶態

②對狀態切換的理解

為什么執行自定義函數時要做權限切換?直接用內核態執行不行嗎?自定義函數存在用戶區,需要用戶態,而內核態權限更高,切換回用戶態是為了避免安全風險,防止內核態被利用。同時內核態進入用戶態后執行自定義函數,意味著用戶態的操作后果自負!

③對執行流概念的深化

我們執行完自定義函數后,想要回到主程序。為什么不直接回去,反而還要進入內核態呢?實際上自定義函數和主程序沒有任何關系,在程序中不存在任何調用關系,信號處理和主程序是兩個完全不同的執行流,因此只能先返回到內核。當觸發硬件中斷,OS會保護現場,存儲各個寄存器的狀態。其中pc寄存器就保存下一條指令的地址,在這里就是主執行流的下一條指令的地址。因此回到用戶態,需要在內核態調用sys_sigreturn()函數,恢復上下文,才可以回到初始時的在主程序執行流。

到這里,我們也能徹底理解信號處理沒有新開一個進程,主執行流和信號捕捉執行流,信號捕捉執行流沒有在主執行流中被調用,而只是一個主執行流中的分支,進程調用過程中兩個分支不會沖突。

下面是執行流切換的過程,仔細體會

(7)volatile

①可重入函數

若一個函數被兩個以上執行流同時進入,就有可能遇到下面這種情況,這是單執行流的情況下遇不到的。


因此實例的insert函數是不可重入函數。相對的,還有可重入函數,也就是可以被被兩個以上執行流同時進入同時不發生錯誤的函數。怎么判斷呢?

只要使用了全局資源的,new了空間的,基本都是不可重入的,使用的都是局部變量的就可能是可重入的基本上STL都不可重入,大部分函數也都不可重入。但也有專門設計的系統接口帶_r,表示可重入。

volatile、編譯器優化

gcc有優化選項 -O0基礎優化,-O1,-O2,-O3優化級別依次增加。

對于主程序執行流和信號處理執行流來說,由于它們從語法上沒有任何聯系,但實際上可以通過全局資源聯系,編譯時就有可能被優化出bug。

若在主執行流中對一個全局變量沒有修改,而實際上這個全局變量在信號捕捉執行流中被處理。對于高優化的編譯器來說,這個全局變量在信號捕捉執行流中的處理無效。我們要從底層來理解優化。

當編譯器優化很大時,一些主執行流沒有修改的變量會變成寄存器變量,這個變量永遠無法被修改。當我們使用這個變量來進行判斷時,邏輯判斷會直接用寄存器里面的值進行判斷而不會使用內存的數據這就導致信號捕捉執行流中修改變量不會生效,寄存器 + 優化屏蔽了內存的可見性。

如果擔心被優化導致出現bug,我們可以使用volatile關鍵字修飾全局變量,volatitl int flag = 0;就不會被寄存器屏蔽了,這個關鍵字相當于告訴編譯器不要對該變量進行任何優化,以保持內存可見性

4.信號拓展

(1)SIGCHLD

父進程一般關心子進程什么時候死,這樣好回收,以免出現孤兒或者僵尸。事實上,子進程退出時都會向父進程發送SIGCHLD信號,告訴父進程自己結束了。不過默認情況下SIGCHLD的Action是Ign(忽略)。我們可以手動捕獲這個信號,當父進程收到信號時再去wait,這樣就能實現父子進程異步執行,而不是讓父進程一直阻塞在原地。

但是有個問題,即信號處理過程中最多允許再接收一個信號,后續的沒意義(pending已經為1了),所以每次需要waitpid + WNOHANG循環,用返回值來判斷是沒等完還是等完了。

僅Linux下,signal(SIGCHLD, SIG_IGN)處理后,這樣fork出來的子進程在終止時會自動清理掉,沒有僵尸,不過父進程也得不到status。這里可認為是Linux的特殊處理,僅僅用來處理僵尸的情況。

(2)SIGALRM

alarm(seconds)函數可以設置一個一次性鬧鐘信號(只會響一次,重復使用需要多次調用),鬧鐘時間到了之后會發送一個14號SIGALRM信號,默認就是Term終止。我們可以捕獲它,利用alarm寫一個統計服務器1s執行某種操作多少次的代碼,可以用alarm來對比IO對效率的影響有多大等操作。

alarm(0)取消鬧鐘,其返回值是鬧鐘剩余時間。如果鬧鐘自己響了,那返回值就是0。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/63640.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/63640.shtml
英文地址,請注明出處:http://en.pswp.cn/web/63640.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

opencv中的色彩空間及其轉換

在 OpenCV 中,色彩空間(Color Space)指的是表示顏色的一種方式,或是用數學模型對顏色的表達。不同的色彩空間采用不同的方式來描述顏色的三要素(如亮度、飽和度、色調),因此可以在不同的應用場景…

OPPO 數據分析面試題及參考答案

如何設計共享單車數據庫的各個字段? 對于共享單車的數據庫設計,首先考慮用戶相關的字段。用戶表可以包含用戶 ID,這是一個唯一標識符,用于區分不同用戶;姓名,記錄用戶的真實姓名;聯系方式,比如手機號碼,方便在出現問題時聯系用戶;注冊時間,記錄用戶何時開始使用共享…

在Ubuntu下運行QEMU仿真FreeBSD riscv64系統

在Ubuntu下運行QEMU仿真FreeBSD riscv64系統 突發奇想,嘗試在Ubuntu下運行QEMU仿真FreeBSD riscv64系統, 參考這篇文檔:手把手教你在QEMU上運行RISC-V Linux_qemu 運行 .bin-CSDN博客 并參考FreeBSD的Wiki:riscv - FreeBSD Wik…

大模型微調---Prompt-tuning微調

目錄 一、前言二、Prompt-tuning實戰2.1、下載模型到本地2.2、加載模型與數據集2.3、處理數據2.4、Prompt-tuning微調2.5、訓練參數配置2.6、開始訓練 三、模型評估四、完整訓練代碼 一、前言 Prompt-tuning通過修改輸入文本的提示(Prompt)來引導模型生…

Visual Studio 、 MSBuild 、 Roslyn 、 .NET Runtime、SDK Tools之間的關系

1. Visual Studio Visual Studio 是一個集成開發環境(IDE),為開發者提供代碼編寫、調試、測試和發布等功能。它內置了 MSBuild、Roslyn 和 SDK Tools,并提供圖形化界面來方便開發者進行項目管理和構建。與其他組件的關系&#xf…

Winnows基礎(2)

Target 了解常見端口及服務,熟練cmd命令,編寫簡單的 .bat 病毒程序。 Trail 常見服務及端口 80 web 80-89 可能是web 443 ssl心臟滴血漏洞以及一些web漏洞測試 445 smb 1433 mssql 1521 oracle 2082/2083 cpanel主機管理系統登陸(國外用的…

Edge Scdn用起來怎么樣?

Edge Scdn:提升網站安全與性能的最佳選擇 在當今互聯網高速發展的時代,各種網絡攻擊層出不窮,特別是針對網站的DDoS攻擊威脅,幾乎每個行業都可能成為目標。為了確保網站的安全性與穩定性,越來越多的企業開始關注Edge …

通信技術以及5G和AI保障電網安全與網絡安全

摘 要:電網安全是電力的基礎,隨著智能電網的快速發展,越來越多的ICT信息通信技術被應用到電力網絡。本文分析了歷史上一些重大電網安全與網絡安全事故,介紹了電網安全與網絡安全、通信技術與電網安全的關系以及相應的電網安全標準…

梯度(Gradient)和 雅各比矩陣(Jacobian Matrix)的區別和聯系:中英雙語

雅各比矩陣與梯度:區別與聯系 在數學與機器學習中,梯度(Gradient) 和 雅各比矩陣(Jacobian Matrix) 是兩個核心概念。雖然它們都描述了函數的變化率,但應用場景和具體形式有所不同。本文將通過…

時間序列預測論文閱讀和相關代碼庫

時間序列預測論文閱讀和相關代碼庫列表 MLP-based的時間序列預測資料DLinearUnetTSFPDMLPLightTS 代碼庫以及論文庫:Time-Series-LibraryUnetTSFLightTS MLP-based的時間序列預測資料 我會定期把我的所有時間序列預測論文有關的資料鏈接全部同步到這個文章中&#…

引言和相關工作的區別

引言和相關工作的區別 引言 目的與重點 引言主要是為了引出研究的主題,向讀者介紹為什么這個研究問題是重要且值得關注的。它通常從更廣泛的背景出發,闡述研究領域的現狀、面臨的問題或挑戰,然后逐漸聚焦到論文要解決的具體問題上。例如,在這篇關于聯邦學習數據交易方案的…

GitLab分支管理策略和最佳實踐

分支管理是 Git 和 GitLab 中非常重要的部分,合理的分支管理可以幫助團隊更高效地協作和開發。以下是一些細化的分支管理策略和最佳實踐: 1. 分支命名規范 ? 主分支:通常命名為 main 或 master,用于存放穩定版本的代碼。 ? …

批量提取zotero的論文構建知識庫做問答的大模型(可選)——含轉存PDF-分割統計PDF等

文章目錄 提取zotero的PDF上傳到AI平臺保留文件名代碼分成20個PDF視頻講解 提取zotero的PDF 右鍵查看目錄 發現目錄為 C:\Users\89735\Zotero\storage 寫代碼: 掃描路徑‘C:\Users\89735\Zotero\storage’下面的所有PDF文件,全部復制一份匯總到"C:\Users\89735\Downl…

LabVIEW實現NB-IoT通信

目錄 1、NB-IoT通信原理 2、硬件環境部署 3、程序架構 4、前面板設計 5、程序框圖設計 6、測試驗證 本專欄以LabVIEW為開發平臺,講解物聯網通信組網原理與開發方法,覆蓋RS232、TCP、MQTT、藍牙、Wi-Fi、NB-IoT等協議。 結合實際案例,展示如何利用LabVIEW和常用模塊實現物聯網…

面試題整理9----談談對k8s的理解2

面試題整理9----談談對k8s的理解2 1. Service 資源1.1 ServiceClusterIPNodePortLoadBalancerIngressExternalName 1.2 Endpoints1.3 Ingress1.4 EndpointSlice1.5 IngressClass 2. 配置和存儲資源2.1 ConfigMap2.2 Secret2.3 PersistentVolume2.4 PersistentVolumeClaim2.5 St…

精準采集整車信號:風丘混合動力汽車工況測試

一 背景 混合動力汽車是介于純電動汽車與燃油汽車兩者之間的一種新能源汽車。它既包含純電動汽車無污染、啟動快的優勢,又擁有燃油車續航便捷、不受電池容量限制的特點。在當前環境下,混合動力汽車比純電動汽車更符合目前的市場需求。 然而&#xff0c…

帶標題和不帶標題的內部表

什么是工作區? 什么是工作區?簡單來說,工作區是單行數據。它們應具有與任何內部表相同的格式。它用于一次處理一行內部表中的數據。 內表和工作區的區別 ? 一圖勝千言 內表的類型 有兩種類型的內表: 帶 Header 行…

【圖像分類實用腳本】數據可視化以及高數量類別截斷

圖像分類時,如果某個類別或者某些類別的數量遠大于其他類別的話,模型在計算的時候,更傾向于擬合數量更多的類別;因此,觀察類別數量以及對數據量多的類別進行截斷是很有必要的。 1.準備數據 數據的格式為圖像分類數據集…

【Leetcode 每日一題】2545. 根據第 K 場考試的分數排序

問題背景 班里有 m m m 位學生,共計劃組織 n n n 場考試。給你一個下標從 0 0 0 開始、大小為 m n m \times n mn 的整數矩陣 s c o r e score score,其中每一行對應一位學生,而 s c o r e [ i ] [ j ] score[i][j] score[i][j] 表示…

React系列(八)——React進階知識點拓展

前言 在之前的學習中,我們已經知道了React組件的定義和使用,路由配置,組件通信等其他方法的React知識點,那么本篇文章將針對React的一些進階知識點以及React16.8之后的一些新特性進行講解。希望對各位有所幫助。 一、setState &am…