Linux信號的誕生與歸宿:內核如何管理信號的生成、阻塞和遞達?

個人主頁:敲上癮-CSDN博客

個人專欄:Linux學習、游戲、數據結構、c語言基礎、c++學習、算法

目錄

一、認識信號

二、信號的產生

1.鍵盤輸入

2.系統調用

3.系統指令

4.硬件異常

5.軟件條件

三、信號的保存

1.block

2.pending

3.handler

四、信號的捕捉

五、核心轉儲

六、從不可重入函數

七、特殊信號

9號和19號信號

SIGCHIL信號


一、認識信號

????????什么是信號?信號是一種異步事件通知機制,類似于生活中的紅綠燈、鬧鐘、電話鈴等,用于中斷當前任務并提醒處理新事件。

????????注:異步就是「發起一個任務后不用干等著,先做別的事,等結果好了再回來處理」

類比生活中的信號,我們來理解一下進程中信號相關的基本結論如下:

  • 進程在信號沒有產生時就知道各個信號該如何處理了。
  • 信號產生后不必立即處理,可以稍等一會,合適的時候處理。
  • 進程內已經內置了對信號的識別和處理機制。
  • 信號種類很多,產生信號的方式也很多。

信號的處理有這三種方式:

  • 默認處理方法
  • 自定義處理方法
  • 忽略處理

二、信號的產生

在命令行中查找信號的相關信息,使用如下指令:

kill -l

我們可以得到這樣一張表:

注意:這里的信號個數并不是64個,如上表中并沒有32和33信號。

其中1~31為普通信號,34~64為實時信號,在這里我們只探討普通信號。?

1.鍵盤輸入

? ? ? ? 在我們運行程序時通常會用Ctrl+c來使程序退出,這其實是向前臺程序發送2號信號。除此之外還有Ctrl+\,表示發送3號信號,同樣是讓程序退出,2號信號與3號信號的區別將在下文核心轉儲部分詳細講解。

? ? ? ? Ctrl+z:發送20號信號,讓程序暫停。

這些就是通過鍵盤發送信號的一種方式,如何驗證呢?

我們可以使用以下函數:

signal函數用于改變信號的處理方法,即自定義信號處理方法。

signal聲明:

#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
  • 參數signum:傳入一個信號編號或信號名稱。
  • 參數handler:傳入自定義的信號處理方法,即一個返回類型為void*,參數為int類型的函數。
  • 返回值:?返回?舊的信號處理函數(函數指針)

注:signal內部會將signum作為參數傳入handler函數。

測試代碼:?

void handler(int sig)
{cout<<"正在處理"<<sig<<"號信號"<<endl;
}
int main()
{   int cnt=0;signal(SIGINT,handler);while(true){cout<<"Run: "<<cnt++<<endl;sleep(1);}
}

注意:由于2號信號處理方法已被改變,Ctrl+c無法殺死程序,可以使用Ctrl+\。?

????????當有多個程序在運行時,會分為前臺和后臺程序,前臺程序只有一個,后臺程序可以有多個鍵盤輸入的信息只能被前臺程序讀取。例如,上述代碼生成的可執行程序test,當我們運行test時它默認是前臺程序,ls,cd,mkdir等指令會失效。因為shell命令行程序已經切換到后臺了。

  • ./test:放在前臺運行。
  • ./test &:放在后臺運行。

切換前后臺程序的方法:

方法一:

  1. jobs:查看所有后臺任務。
  2. fg 任務號:特定的進程提到前臺。

方法二:

  1. Ctrl+z:暫停當前進程,然后自動把后臺提到前臺
  2. bg 任務號:把剛才暫停的任務恢復運行。

2.系統調用

除了鍵盤產生信號,我們還可以直接用kill、raise、abort這些接口向系統發信號。

使用方法如下(這里我們暫不對返回值進行討論):

kill函數聲明:

int kill(pid_t pid, int sig);
  • 參數pid:傳入需要發信號的進程pid。
  • 參數sig:傳入需要發送的信號編號。?
  • 功能:向任意進程發送信號

raise函數聲明:

int raise(int sig);
  • 參數sig:傳入需要發送的信號編號。
  • 功能:向自己發送信號

abort函數聲明:

void abort(void);
  • 功能:向自己發送6號信號

我們同樣可以使用改變信號處理的方法來驗證。?這里就不展示。

3.系統指令

kill 信號編號 進程pid

使用kill指令向指定的進程發送指定的信號。?

4.硬件異常

????????發送信號方式還有硬件異常,比如引用空指針,除0等等這些非法操作最終是反應到了硬件上,然后產生信號。比如我們可以這樣做測試:

void sig_handle(int sig)
{cout<<"接收到信號:"<<sig<<endl;exit(1);
}
int main()
{for(int i=1;i<32;i++)signal(i,sig_handle);int a = 10;a /= 0;//int* p = nullptr;//*p = 10;return 0;
}

除0觸發8號信號,引用空指針觸發11號信號。

5.軟件條件

????????軟件條件觸發信號,比如alarm,?alarm函數是一個用于設置定時器的系統調用,主要作用是讓內核在指定的時間后向進程發送SIGALRM信號。它的核心功能是提供一種簡單的超時機制或定時任務調度。

alarm聲明:

unsigned int alarm(unsigned int seconds);
  • 參數seconds:是定時器倒計時時間(單位:秒)。若為?0,表示取消之前設置的定時器。
  • 返回值:之前未完成的定時器剩余時間(秒)。例如:如果之前設置了 5 秒的定時器,3 秒后再次調用?alarm(2),返回值為?2(剩余時間),新定時器將在 2 秒后觸發。

三、信號的保存

????????在開篇就提到信號并不一定是產生后就馬上被處理的,所以需先將它保存下來。而信號又分為兩種狀態:信號未決,信號遞達

  • 信號未決:信號被保存但沒有被處理。
  • 信號遞達:信號被處理。

進程可以阻塞信號,被阻塞的信號產生時會保持在未決狀態,直到解除阻塞才能被遞達。

注:阻塞和忽略是不同的,忽略是在遞達后的一種處理方式。

在程序中信號的相關信息會被保存在block、pending、handler這三張表中。

  • block表:記錄的是信號的阻塞狀態。
  • pending表:記錄的是未決情況。
  • handler表:儲存的是信號的處理方法。

????????從上圖來看,每個信號只有?個bit的未決標志,?0即1,不記錄該信號產?了多少次,阻塞標志也是這樣表?的。因此,未決和阻塞標志可以?相同的數據類型sigset_t來存儲,sigset_t稱為信號集,這個類型可以表?每個信號的“有效”或“?效”狀態,在阻塞信號集中“有效”和“?效”的含義是該信號是否被阻塞,?在未決信號集中“有效”和“?效”的含義是該信號是否處于未決狀態。

????????阻塞信號集也叫作當前進程的“信號屏蔽字”。

1.block

關于信號集的處理函數有這些:

  • int sigemptyset(sigset_t *set);
  • int sigaddset(sigset_t *set, int signo);
  • int sigdelset(sigset_t *set, int signo);
  • int sigismember(const sigset_t *set, int signo);

功能:

  • sigemptyset:相當于初始化,使其中所有信號的對應bit清零,表示該信號集不包含任何無效信號
  • sigaddset:添加無效信號。
  • sigdelset:刪除無效信號。
  • sigismember:查看一個信號是否有效,返回0表示有效,返回1表示無效。

block表儲存的是信號的阻塞狀態,用的是位圖的原理,1表示阻塞,0表示未阻塞。

????????以上這些函數只是用來設置信號集,接下來使用函數sigprocmask把信號集設置到程序中,使其信號屏蔽字改變。

sigprocmask函數聲明如下:

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

參數how:需要我們傳入一個可選參數,表示要做的操作,這個參數可以是:

mask表示的是程序當前的信號屏蔽字,這里我們最常用的是SIG_SETMASK選項

參數set:把設置好的信號屏蔽字(類型為signal_t*)傳入。

參數oldset:這是一個輸出型參數,獲取到舊的信號屏蔽字。

測試代碼:

void handler(int sig)
{cout<<"正在處理"<<sig<<"號信號"<<endl;
}
int main()
{ signal(2,handler);sigset_t block,oblock;sigemptyset(&block);sigaddset(&block,SIGINT);//屏蔽2號信號sigprocmask(SIG_SETMASK,&block,&oblock);while(true){cout<<"hello linux"<<endl;sleep(1);}return 0;
}

2.pending

????????pending這張表用來標記信號是否處于未決狀態。函數sigpending可以獲取pending表

聲明如下:

int sigpending(sigset_t *set);

參數set:這是一個輸出型參數,用來獲取到pending表的信息。

然后我們可以借助setismember來打印pending表的信息。?

測試代碼:

int main()
{sigset_t sig;sigpending(&sig);for(int i=31;i>=1;i--){//判斷i號信號是否未決if(sigismember(&sig,i))cout<<1;else cout<<0;}return 0;
}

注:一個信號在即將要被處理前會把pending表對應的bit位改為0,而不是在處理完后修改。

3.handler

????????handler表是一個函數指針數組,儲存了每一個信號的處理方式。SIG_DEL表示默認處理,SIG_IGN表示忽略處理,然后還可以使用函數signal設定自定義處理方法。

其中SIG_DEL,SIG_IGN可作為參數傳入signal函數中。

除了使用signal函數設置自定義處理方法外,還可以使用sigaction。

sigaction聲明如下:

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

其中sigact是一個結構體類型,聲明如下:

struct sigaction {void     (*sa_handler)(int);void     (*sa_sigaction)(int, siginfo_t *, void *);sigset_t  sa_mask;int       sa_flags;void     (*sa_restorer)(void);
};
  • sa_handler:自定義的信號處理函數。
  • sa_mask:在處理該信號的過程中需要阻塞的信號。

????????其它成員變量用得很少這里就不再探討。所以與signal接口相比,sigaction并表示簡單的設置自定義處理方法,它還能做更復雜的處理。

關于sigaction的參數:

  • 參數signum:需要設置的信號編號
  • 參數act:傳入一個自定義的struct sigaction類型的地址
  • 參數oldact:一個輸出型參數,獲取到舊的struct sigaction信息。

測試代碼:

void handler(int sig)
{cout << "收到信號" << sig << endl;while (true){sigset_t s;sigpending(&s);for (int i = 31; i >= 1; i--){if (sigismember(&s, i)) cout << '1';else cout << '0';}cout << endl;sleep(1);}
}
int main()
{struct sigaction act, oact;act.sa_handler = handler;sigemptyset(&act.sa_mask);sigaddset(&act.sa_mask, 2);sigaddset(&act.sa_mask, 3);sigaction(SIGINT, &act, &oact);while (true){cout << "hello linux! my pid:" << getpid() << endl;sleep(1);}return 0;
}

測試結果:

四、信號的捕捉

????????接下來我們來學習信號的處理,在此之前最好對CPU中斷機制有所了解,可以通過下面這篇文章進行學習:操作系統的心臟節拍:CPU中斷如何驅動內核運轉?-CSDN博客

????????如上圖是系統處理自定義信號的流程圖,而默認處理和忽略處理就比較簡單,只到第3步。

????????注:無論你寫的程序是否有系統調用,是否觸發異常等 都有機會進入內核狀態,因為在CPU中還存在著時鐘中斷能多次使你的程序陷入內核。

我們可以把自定義信號處理中狀態的轉化抽象成這樣一個圖:

????????其中用戶態和內核態之間做了四次轉化,如圖紅圈部分,而pending表的檢查是在內核態內完成的。

五、核心轉儲

我們通過輸入以下指令可以看到信號相關的信息:

man 7 signal

如下Action這一欄的表示默認行為

標識符全稱含義
TermTerminate終止進程。進程會立即終止。
CoreCore Dump + Terminate生成核心轉儲文件并終止進程。進程終止時生成?core?文件(用于調試)。
IgnIgnore忽略信號。進程不會采取任何動作。
ContContinue恢復進程執行。如果進程被暫停(如?SIGSTOP),則恢復運行。
StopStop暫停進程。進程會被掛起,直到收到?SIGCONT?信號。

????????之前我們說過Ctrl+c和Ctrl+\都是使進程退出,但并沒有講它們的區別,其實就是Ctrl+\會比Ctrl+c多產生一個core文件,它是把內核中核心數據轉儲到磁盤上,這個文件可能儲存到當前路徑,也有可能儲存到路徑:/var/lib/systemd/coredump中。

????????但在一般情況下是生成不了這個core文件的,因為云服務器出于?安全性、資源管理?和?合規性?的考慮,默認關閉了核心轉儲(Core Dump)。比如惡意用戶可能故意觸發程序崩潰,生成大量核心轉儲文件,耗盡磁盤空間,導致系統癱瘓。

通過以下指令可以看到關于core dump的信息:

ulimit -a

如下:

????????我們看到code file size為0,表明核心轉儲已經被關閉了,可以通過ulimit -c指令臨時打開,并設置大小。

比如:

ulimit -c 40960

debug:

core文件有什么作用呢?

? ? ? ? 我們讓程序生成core文件通常是用來查找bug的,使用gdb打開出bug的程序,然后輸入指令 core-file core后程序能跳轉到出問題的具體代碼的位置。

core dump標志位:

在使用waitpid回收子進程時,其中有一個輸出型參數,用來獲取?進程退出狀態。如下:

????????這里第8個比特位記錄的就是是否生成core文件,1表示生成core文件,0表示沒有生成。

六、從不可重入函數

????????在我們執行程序過程中,可能任務執行到一半就因接收到信號,而先去處理信號了。那么如果程序和信號處理的是同一個數據呢,會出現什么問題?

?????????像這樣會被兩個及以上的執行流同時調用而發生不可預料的結果的函數被稱為不可重入函數,需要警惕這樣的事情發生。而函數內部只有自己的臨時變量,這樣的函數是可重入的

七、特殊信號

9號和19號信號

  • SIGKILL(9)?的默認行為是?立即終止進程

  • SIGSTOP(19)?的默認行為是?強制暫停進程(進入停止狀態,直到收到SIGCONT)。

????????這兩個信號的默認行為是操作系統強制執行的,進程無法干預,也就是無法對它們進行阻塞、忽略、自定義處理方法等。

????????這是出于操作系統的?安全性和穩定性?考慮,試想一下如果所有信號都可以被阻塞、忽略或自定義處理方法。那么我們就可以做這么一個惡意程序,把所有信號都阻塞了,然后寫一個死循環,那么程序不就無法退出了嗎?還可以更狠一點,在循環內不斷申請內存空間。

所以這樣的設計可以防止惡意進程失控,為管理員提供終極控制權。

SIGCHIL信號

17號信號(SIGCHIL)是在子進程退出后向父進程發送的。

????????當我們知道這一點我們就可以自定義17號信號的處理方法,讓父進程對子進程的等待操作在信號處理里面完成,這樣父進程就不用去關心子進程的回收問題,從而實現異步功能

代碼示例:

void handler(int sig)
{while(true){int n = waitpid(-1,nullptr,WNOHANG);if(n==0) break;else if(n<0){perror("waitpid");exit(1);}elsecout<<"wait success: "<<n<<endl;}
}
int main()
{signal(17,handler);for(int i=0;i<10;i++){sleep(1);int id=fork();if(id==0){cout<<"child process:"<<getpid()<<" exit "<<endl;sleep(1);exit(1);}}return 0;
}

????????我們回想一下操作系統為什么要在子進程退出后設計一個僵尸進程讓用戶主動回收呢?子進程退出后操作系統直接把它回收不好嗎?

? ? ? ? 其實這樣設計是很合理的,我們創建子進程不就是讓子進程異步去幫我們完成任務嘛,那么它完成得怎么樣我們總應該要知道,所以才有了僵尸進程來儲存任務的完成情況。而當我們并不關心子進程的任務完成情況時,那么是不是就用不著僵尸進程這種機制啊?

? ? ? ? 答案是:是的!所以操作系統也為我們設計了一種不生用成僵尸進程的方法。

????????只需要把17號信號的處理方法設置為忽略處理,即SIG_IGN(上文handler部分已講解),這樣操作系統就不會給我們生成僵尸進程。

????????細心的讀者可能會發現,17號信號的默認行為就是Ign(忽略)嗎?在信號信息表的Action這一欄可以找到。

????????要注意用戶不做任何自定義信號處理時,所有信號都是默認處理方式(即SIG_DFL),而17號的默認行為是Ign而已。和忽略處理(即SIG_IGN)是不同的,是否忽略必須讓用戶自己指明。

非常感謝您能耐心讀完這篇文章。倘若您從中有所收獲,還望多多支持呀!74c0781738354c71be3d62e05688fecc.png

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

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

相關文章

DeepSeek API集成開發指南——Flask示例實踐

DeepSeek API集成開發指南——Flask示例實踐 序言&#xff1a;智能化開發新范式 DeepSeek API提供了覆蓋自然語言處理、代碼生成等多領域的先進AI能力。本文將以一個功能完備的Flask示例系統為載體&#xff0c;詳解API的集成方法與最佳實踐。通過本案例&#xff0c;開發者可快…

Linux環境下安裝部署Docker

windows下連接Linux&#xff1a; 打開終端&#xff1a; //ssh遠程連接 ssh root192.168.xx.xx//輸入賬號密碼 root192.168.xx.xxs password: ssh連接成功&#xff01; 安裝Docker&#xff1a; //安裝Docker yum install -y yum-utils device-mapper-persistent-data lvm2 …

開源CDN產品-GoEdge

一、背景 上篇文章分析了一下CDN的基本原理以及使用代碼實現了一個乞丐版的智能DNS調度器。從整個例子我們可以清晰了解到CDN原理&#xff0c;也就那么回事。 但是&#xff0c;之前也講過了&#xff0c;CDN產品融合的技術比較雜、也比較多。所以我就想著&#xff0c;萬物皆有開…

正則表達式-萬能表達式

1、正則 正則表達式是一組由字母和符號組成的特殊文本, 它可以用來從文本中找 出滿足你想要的格式的句子. {“basketId”: 0, “count”: 1, “prodId”: #prodId#, “shopId”: 1, “skuId”: #skuId#} #prodId# re相關的文章&#xff1a; https://www.cnblogs.com/Simple-S…

javaWeb Router

一、路由簡介 1、什么是路由&#xff1f; - 定義&#xff1a;路由就是根據不同的 URL 地址展示不同的內容或頁面。 - 通俗理解&#xff1a;路由就像是一個地圖&#xff0c;我們要去不同的地方&#xff0c;需要通過不同的路線進行導航。 2、路由的作用 - 單頁應用程序…

【前端】使用 HTML、CSS 和 JavaScript 創建一個數字時鐘和搜索功能的網頁

文章目錄 ?前言?一、項目結構?二、HTML 結構?三、CSS 樣式?四、JavaScript 功能?五、運行效果?總結 標題詳情作者JosieBook頭銜CSDN博客專家資格、阿里云社區專家博主、軟件設計工程師博客內容開源、框架、軟件工程、全棧&#xff08;,NET/Java/Python/C&#xff09;、數…

聚焦應用常用功能,提升用戶體驗與分發效率

隨著HarmonyOS應用的持續發展&#xff0c;應用的功能將越來越豐富&#xff0c;實際上80%的用戶使用時長都會集中在20%的特性上&#xff0c;其余的功能可能也僅僅是面向部分用戶。 用戶在下載應用時&#xff0c;如果應用包含大量的功能和資源&#xff0c;可能會導致下載時間過長…

OCR 識別案例

OCR 識別案例 注意點&#xff1a;輸入圖像尺寸比例盡量和參與模型訓練的數據集比例相似&#xff0c;識別效果會更好。 1、pytesseract Pytesseract是一個Python的光學字符識別&#xff08;OCR&#xff09;工具&#xff0c;它作為Tesseract OCR引擎的封裝&#xff0c;允許你在…

IP大洗牌ipv6強勢來襲!!!【ipv6配置及應用】

前言 隨著時代的發展&#xff0c;IPv4&#xff08;互聯網協議第四版&#xff09;已逐漸無法滿足全球互聯網爆炸式增長的需求。自20世紀80年代誕生以來&#xff0c;IPv4憑借其簡潔的架構和約43億的地址容量&#xff0c;支撐了互聯網的早期擴張。然而&#xff0c;在移動互聯網、物…

OpenAI 推出圖像生成新突破:GPT-4o 實現圖像編輯對話化

關鍵要點 OpenAI 推出了 4o 圖像生成功能&#xff0c;集成于 GPT-4o&#xff0c;提供精準且逼真的圖像生成。 它似乎適用于多種用戶&#xff0c;包括免費用戶&#xff0c;API 訪問預計幾周內推出。 安全措施包括 C2PA 元數據和內容屏蔽&#xff0c;限制生成不適當圖像。 研究…

如何快速對比兩個不同的excel文件中的單元格的數據是否完全相同 并把不同的單元格的背景顏色更改為紅色?

要快速對比兩個不同的Excel文件中的單元格數據是否完全相同&#xff0c;并將不同的單元格背景顏色更改為紅色&#xff0c;可以使用Excel的以下幾種方法&#xff1a; 方法一&#xff1a;使用條件格式 打開兩個Excel文件。將一個文件的內容復制到另一個文件的新工作表中&#x…

口腔種植全流程AI導航系統及輔助診療與耗材智能化編程分析

一、系統架構與編程框架設計 口腔種植全流程人工智能導航系統的開發是一項高度復雜的多學科融合工程,其核心架構需在醫學精準性、工程實時性與臨床實用性之間實現平衡。系統設計以模塊化分層架構為基礎,結合高實時性數據流與多模態協同控制理念,覆蓋從數據采集、智能決策到…

nginx配置頁面緩存,前端每次打包生成新的js文件

前端需要處理的&#xff1a;使用時間戳作為文件名 // nuxt.config.js export default {build: {filenames: {app: ({ isDev }) > isDev ? [name].js : [name].${Date.now()}.js, // 生產環境用時間戳chunk: ({ isDev }) > isDev ? [name].js : [name].${Date.now()}.j…

4.Socket類、InetAddr類、Epoll類實現模塊化

目錄 1. InetAddr類 類定義 代碼說明 類實現 2.Socket類 類定義 類實現 3. Epoll類 類定義 構造與析構函數 方法實現 類實現 4. 使用模塊化設計 示例使用&#xff08;main.cpp) 5. 運行程序 隨著程序復雜度的增加&#xff0c;單一的面向過程的代碼會變得難以理…

視頻生成的測試時Scaling時刻!清華開源Video-T1,無需重新訓練讓性能飆升

來源 | 機器之心 視頻作為包含大量時空信息和語義的媒介&#xff0c;對于 AI 理解、模擬現實世界至關重要。視頻生成作為生成式 AI 的一個重要方向&#xff0c;其性能目前主要通過增大基礎模型的參數量和預訓練數據實現提升&#xff0c;更大的模型是更好表現的基礎&#xff0c…

Go 語言標準庫中time模塊詳細功能介紹與示例

以下是 Go 語言 time 模塊的詳細說明及示例&#xff0c;涵蓋時間操作、定時器、時區處理等核心功能&#xff1a; 一、時間基礎操作 1. 獲取時間 // 當前本地時間 now : time.Now() fmt.Println(now) // 2023-08-04 15:30:45.123456 0800 CST// 構造指定時間 t : time.Date(20…

【強化學習】基于深度強化學習的微能源網能量管理與優化策略研究【Python】

目錄 主要內容 程序要點 2.1 微能源網系統組成 2.2 強化學習及Q學習算法 部分代碼 運行結果 下載鏈接 主要內容 該程序借助深度 Q 網絡&#xff08;DQN&#xff09;&#xff0c;學習預測負荷、風 / 光可再生能源功率輸出及分時電價等環境信息&#xff0c;運用…

dom0-kernel: /thermal-zones/soc_max/cooling-maps/map0: could not find phandle 2

問題描述&#xff1a; 由于soc_max下某個節點找不到&#xff0c;到時dom0-kernel后面有很多有關thermal熱管理之類報錯 問題解決及其原因分析&#xff1a; 這是因為在Xen解析相關節點時&#xff0c;soc_max下的某個節點被跳過了&#xff0c;注釋掉相關的cpu節點處理dom0就可以找…

關于計算機視覺中的插值小記

計算機視覺中的插值&#xff08;Interpolation&#xff09;講解 插值&#xff08;Interpolation&#xff09;在計算機視覺中是一項基礎操作&#xff0c;常用于圖像縮放、旋轉、去噪、圖像重建等任務。其核心思想是在已知數據點之間進行推測&#xff0c;估計未知的像素值或特征…

計算機網絡--傳輸層(1)

第五章 傳輸層 一、傳輸層基本功能 進程到進程的邏輯通信 套接字&#xff08;Socket&#xff09;&#xff1a;IP地址:端口號 IP地址&#xff1a;標識主機&#xff08;網絡層功能&#xff09;端口號&#xff1a;16位整數&#xff08;0-65535&#xff09;&#xff0c;標識進程 熟…