【Linux】進程 信號的產生

🌻個人主頁:路飛雪吖~

? ? ? ?🌠專欄:Linux


目錄

一、掌握Linux信號的基本概念

?🌠前臺進程 VS 后臺進程

🌠 小貼士:

🪄?個系統函數 --- signal()

?🪄查看信號 --- man 7 signal

二、軟硬件上理解 :?OS如何進行信號處理

?硬件上理解

🌠 信號 VS 硬件中斷

?軟件:如何理解信號處理?

三、?信號產生的方式

🚩1. 鍵盤產生

🚩2. 系統指令產生? 發送信號? ---- 底層使用的是系統調用?編輯

🚩3. 系統調用 發送信號

🌠? 發送信號的其他函數:

🪄 raise ---?函數可以給當前進程發送指定的信號(??給??發信號)?

🪄 abort ---?自己給自己發了一個特定的終止自己的信號 --- 6號信號[SIGABRT]

🚩4. 由軟件條件 產生信號

?🌠OS內定時器

四、? alarm() 設置重復鬧鐘 ---?簡單快速理解系統鬧鐘

🚩5. 異常?(野指針、 除 0)

?🪄模擬 野指針

?🪄?模擬 除 0

🌠OS怎么知道我們的進程內部出錯了?為什么會陷入死循環?

???除 0 :

???野指針

🌠core VS Term?

?core 的使用 --- 調試

🌠 如果是子進程異常了呢? core 會不會出現?

🌠小結:

?五、信號處理

1. 默認處理動作

2. 忽略:本身就是一種信號捕捉的方法,動作就是忽略

?3. 自定義 捕捉一個信號


? 信號是內置的,進程認識信號,是程序員內置的特性;

? 信號的處理方法,在信號產生之前,就已經準備好了;

? 何時處理信號?先處理優先級很高的,可能并不是立即處理,在合適的時候處理;

? 怎么處理信號:a. 默認行為,b. 忽略信號,c. 自定義動作

信號產生 ---> 信號保存 ---> 信號處理

一、掌握Linux信號的基本概念

// MakefileBIN=sig
CC=g++
SRC=$(shell ls *.cc)
OBJ=$(SRC:.cc=.o)$(BIN):$(OBJ)$(CC) -o $@ $^ -std=c++11%.o:%.cc$(CC) -c $< -std=c++11.PHONY:clean
clean:rm -f $(BIN)
// Signal.cc#include <iostream>
#include <unistd.h>int main()
{while(true){std::cout << "hello world" << std::endl;sleep(1);}return 0;
}

?🌠前臺進程 VS 后臺進程

??前臺進程【./sig】:在命令行所輸入的所有東西都不能執行。

? > Ctrl + c 終止前臺進程:給的是shell,shell在前臺 --> 信號發給進程。

??后臺進程【./sig &】:bash進程依舊可以進行命令行解釋。

? > kill -9 [pid] 終止后臺進程

? > fg [作業號]?

🌠 小貼士:

<1>

?【1 -- 31】:普通信號;

?【34 -- 64】:實時信號。

<2>?

ctrl + c --> 信號發給進程,被OS接受并解釋成為2號【SIGINT】信號,發送給目標進程 -- 對2號信號的默認處理動作是 終止自己!。

🪄?個系統函數 --- signal()

#include <iostream>
#include <unistd.h>
#include <signal.h>void Handler(int signo)
{// 當對應的信號被觸發,內核會將對應的信號編號,傳遞給自定義方法std::cout << "Get a signal, signal number is : " << signo << std::endl;
}int main()
{signal(SIGINT, Handler);// 默認終止 --改成了--> 執行自定義方法:Handler while(true){std::cout << "hello world" << std::endl;sleep(1);}return 0;
}

#include <iostream>
#include <unistd.h>
#include <signal.h>void Handler(int signo)
{// 當對應的信號被觸發,內核會將對應的信號編號,傳遞給自定義方法std::cout << "Get a signal, signal number is : " << signo << std::endl;
}int main()
{signal(SIGQUIT, Handler);// 默認終止 --改成了--> 執行自定義方法:Handler while(true){std::cout << "hello world" << std::endl;sleep(1);}return 0;
}

ctrl + \ :3號信號,默認也是終止進程的。

?🪄查看信號 --- man 7 signal

#include <iostream>
#include <unistd.h>
#include <signal.h>void Handler(int signo)
{// 當對應的信號被觸發,內核會將對應的信號編號,傳遞給自定義方法std::cout << "Get a signal, signal number is : " << signo << std::endl;
}int main()
{// signal 為什么不放在循環里面? 不需要,只需要設置一次就可以了// signal:如果沒有產生2或者3號信號呢? handler不被調用!// signal(SIGINT, Handler);// 默認終止 --改成了--> 執行自定義方法:Handler// signal(SIGQUIT, Handler);// 默認終止 --改成了--> 執行自定義方法:Handlerfor (int signo = 1; signo < 32; signo++)// 捕捉 1--31 號的信號,使得很多方法殺不掉進程,但是有一些信號捕捉不到{signal(signo, Handler);std::cout << "自定義捕捉信號:" << signo << std::endl;}while (true){std::cout << "hello world" << std::endl;sleep(1);}return 0;
}

二、軟硬件上理解 :?OS如何進行信號處理

?硬件上理解

OS怎么知道鍵盤上面有數據?

當按下鍵盤 首先是被驅動程序識別到 按下的按鍵,OS如何知道鍵盤被按下了?--- 硬件中斷?,鍵盤一旦按下,在硬件上 鍵盤 和 CPU 是連接的,在控制信號,輸入設備是直接和中央處理器連接的,輸入設備首先會給中央處理器發送一個中斷信號【硬件電路】,CPU中央處理器收到這個硬件電路之后,立馬就會告訴OS,當前外設有一個外設準備好了,接下來讓OS主動的去把外設的數據拷貝到內存里,此時OS再也不用主動輪詢檢測任何輸入/輸出設備了,只需要等待發生中斷信號 --- 硬件和OS可以并行執行了!

?

🌠 信號 VS 硬件中斷

? 信號是純軟件,模擬中斷的行為;

? 硬件中斷,純硬件。

?軟件:如何理解信號處理?

? 鍵盤上的組合鍵 是先被OS系統識別到【OS是鍵盤真正的管理者,當系統在運行的時候,OS一直在檢測鍵盤上有沒有信息】再發給進程,當進程不能立即處理這個信號時,進程就會記錄下這個信號【信號是從 1-31 連續的數字,進程是否收到1-31這個數字的信號 --- 在 task_struct?里通過位圖記錄 0000 0000 0000 0000 0000 0000 0000 0000,比特位的位置:信號的編號,比特位的內容:是否為0/1,是否收到對應的信號】發送信號的本質是什么?【寫入信號】OS修改目標進程的PCB中的信號位圖【0 -> 1】,操作系統有沒有權利修改進程PCB的位圖?有,OS是進程的管理者,所以 無論以什么方式發送信號,最終 都是轉換到OS,讓OS寫入信號,因為OS是進程的唯一管理者。? ?

? 信號產生有很多種,但是信號發送只有OS;

? 判斷進程是否收到信號:進程里面有信號處理的表結構 sighandler_t arr[32] 函數指針數組,根據PCB里面去查位圖,根據位圖就可以檢測出那個比特位為1,拿到比特位為1,這個數字就可以作為該數組的下標【下標-1】,直接去調用函數指針上的方法。

三、?信號產生的方式

🚩1. 鍵盤產生

當在可執行程序在前臺進程產生之后,按住 ctrl+c ,鍵盤被按下,計算機的CPU識別到鍵盤又被按下的動作,喚醒OS,讓OS去讀取鍵盤山的 ctrl+c ,讀到后將 ctrl + c 解釋成 2號 信號【if(案件 == ctrl + c)】,OS會把 ctrl + c 轉化成一段代碼【向目標前臺進程PCB寫入2號信號,即把比特位 0 --> 1,OS信號發送完成】,發送完成之后,該進程在后續合適的時候調度運行,發現自己收到一個信號,當前進程默認就要執行自己對 2號 信號的處理動作。

🚩2. 系統指令產生? 發送信號? ---- 底層使用的是系統調用

🚩3. 系統調用 發送信號

// MakefileBIN=mykill
CC=g++
SRC=$(shell ls *.cc)
OBJ=$(SRC:.cc=.o)$(BIN):$(OBJ)$(CC) -o $@ $^ -std=c++11%.o:%.cc$(CC) -c $< -std=c++11.PHONY:clean
clean:rm -f $(BIN)
// Signal.cc#include <iostream>
#include <unistd.h>
#include <stdlib.h>
#include <string>
#include <signal.h>// 設置自己的killvoid Usage(std::string proc)
{std::cout << "Usage: " << proc << " signumber processid " << std::endl;
}// ./mykill  1信號    12345進程號
int main(int argc, char *argv[])
{if(argc != 3){Usage(argv[0]);exit(1);}int signumber = std::stoi(argv[1]);// 轉換為整數pid_t id = std::stoi(argv[2]);int n = ::kill(id, signumber);if(n < 0){perror("kill");exit(2);}exit(0);
}

信號發送 本質都是操作系統OS發的!!!

🌠? 發送信號的其他函數:

🪄 raise ---?函數可以給當前進程發送指定的信號(??給??發信號)?

#include <iostream>
#include <unistd.h>
#include <signal.h>int main()
{int cnt = 5;while(true){std::cout << "hahaha alive" << std::endl;cnt--;if(cnt <= 0)raise(9);sleep(1);}
}

🪄 abort ---?自己給自己發了一個特定的終止自己的信號 --- 6號信號[SIGABRT]

int main()
{int cnt = 5;while(true){std::cout << "hahaha alive" << std::endl;cnt--;if(cnt <= 0)// abort();sleep(1);}
}

🚩4. 由軟件條件 產生信號

?SIGPIPE 是?種由軟件條件產生的信號。

🪄 alarm 函數 ---?調? alarm 函數可以設定?個鬧鐘,也就是告訴內核在 seconds 秒之后給當前進程發 (14號)SIGALRM 信號,該信號的默認處理動作是終?當前進程。

int main()
{// 統計我的服務器 1s 可以將計數器累加多少!alarm(1);// 我自己,會在 1s 之后收到一個SIGALARM信號int number = 0;while(true){printf("count: %d\n", number);}}

int number = 0;
void die(int signumber)
{printf("get a sig : %d, count: %d\n", signumber, number);exit(0);
}int main()
{// 統計我的服務器 1s 可以將計數器累加多少!alarm(1);// 我自己,會在 1s 之后收到一個SIGALARM信號signal(SIGALRM, die);while(true){number++;}}

這兩個的寫法 計數器累加的次數為什么會差別這么大呢?

【printf("count: %d\n", number);】里面的 IO 影響了計算的速度!,【while(true) number++;】純CPU計算。

?🌠OS內定時器

? 在操作系統內,要對 進程管理、文件管理、多線程、內存管理 進行管理,同時也要做定時管理,OS在開機之后,是會維護時間的,所以設置的鬧鐘,在OS底層就是設置了一個定時器。?

? 許多進程都可以設置鬧鐘,OS里可以同時存在很多被設置的鬧鐘,所以OS就要管理定時器【先描述,再組織】[struct timer{}] ,OS在每次檢測超時的時候,會把定時器所對應的節點,按順序進行升序排序,變成有序的列表,當有超時的時候,只需要從前往后遍歷,遇到第一個沒有超時的,之前的全部是超時的,遍歷的同時,把超時的【struct timer】執行對應的 【func_t f;函數,給目標進程發送SIGALRM信號】在操作系統內給相應的進程發信號。

? 用堆理解定時器的排序:維護成一個最小堆,用超時時間作為鍵值,所以要想知道定時器有沒有超時,只需要查堆頂就可以了,若堆頂沒有超時,則所有的節點都沒有超時;若堆頂超時,就把堆頂pop出來【堆再重新構建】,去執行相應的操作,重復操作,直到不再超時。

? 所以當我們在調用alarm函數時,就相當于在OS內給我們獲取當前時間【currenttime】和 當前的超時時間【seconds】,然后在內核中設置一個節點,放在堆里面,OS就會在超時之后,直接向目標進程發送SIGALRM信號,并且把該節點釋放掉。

? 鬧鐘的返回值 是什么?鬧鐘剩余時間

int main()
{alarm(10);sleep(4);int n = alarm(0);// 0:取消鬧鐘std::cout << "n: " << n << std::endl;
}

? 當軟件條件就緒時【超時、鬧鐘、定時器】,OS就可以向目標進程發送信號。

四、? alarm() 設置重復鬧鐘 ---?簡單快速理解系統鬧鐘

#include <iostream>
#include <unistd.h>
#include <stdlib.h>
#include <string>
#include <signal.h>
#include <functional>
#include <vector>// 鬧鐘
using func_t = std::function<void()>;int gcount = 0;
std::vector<func_t> gfuncs;// 把信號 更換 成為 硬件中斷
void handler(int signo)
{for(auto &f : gfuncs){f();}std::cout << "gcount : " << gcount << std::endl;alarm(1);// 上面的鬧鐘響了之后,繼續執行
}int main()
{gfuncs.push_back([](){ std::cout << "我是一個內核刷新操作" << std::endl;});gfuncs.push_back([](){ std::cout << "我是一個檢測進程時間片的操作,如果時間片到了,我會切換進程" << std::endl;});gfuncs.push_back([](){ std::cout << "我是一個內存管理操作,定期清理操作系統內部的內存碎片" << std::endl;});alarm(1);// 一次性的鬧鐘,超時alarm會自動被取消signal(SIGALRM, handler);while(true)  // gcount++;{pause();std::cout << "我醒來了..." << std::endl;gcount++;}
}

? 操作系統其實就是一個死循環,當OS啟動之后,會接收外部固定的事件源【時鐘中斷,集成在CPU內部】,每隔很短的時間,向OS觸發硬件中斷,讓OS去執行中斷方法。

? OS的調度、切換、內存管理、系統調用,全都是依靠中斷來完成的。所以OS不應該叫OS,應該叫一個中斷程序。

🚩5. 異常?(野指針、 除 0)

?🪄模擬 野指針

void handler(int signo)
{std::cout << "get a signo: " << signo << std::endl;// 我捕捉了 11 號信號,沒執行默認動作,也沒有退出進程
}int main()
{signal(11, handler);int *p = nullptr;*p = 100;while(true);
}

?🪄?模擬 除 0

void handler(int signo)
{std::cout << "get a signo: " << signo << std::endl;// 我捕捉了 8 號信號,沒執行默認動作,也沒有退出進程
}int main()
{signal(8, handler);int a = 10;a /= 0;while(true);
}

C/C++中,常見的異常,進程崩潰了,原因是 OS給目標進程發送對應錯誤的信號,進而導致該進程退出。

🌠OS怎么知道我們的進程內部出錯了?為什么會陷入死循環?
???除 0 :

狀態寄存器里會有各種描述狀態計算的結果,其中有一個叫做 溢出標記位,正常情況下計算完畢,溢出標記位為0,說明整個計算結果沒有溢出,結果可靠,此時把結果寫回內存里,就完成對應的復制。若對應的溢出標記位為1,就證明CPU內部計算結果出錯了。

當出現溢出,即CPU內部結果出錯了,OS就會知道【CPU[硬件]的中斷有?內部中斷 和 外部中斷,CPU內部一旦出現溢出的錯誤,CPU內部硬件就會觸發內部中斷,就會告訴OS,OS是硬件的管理者,OS在調度、切換,就是在合理的使用CPU資源】,是哪個進程引起的硬件錯誤,OS就會通過信號殺掉進程!即當計算出現硬件錯誤,OS要識別到,就會給目標進程發送對應的信號,殺掉進程!

為什么會陷入死循環【不退出進程】?

這個進程一直沒有退出,還要被調度,進程就會被切換、執行等等,【a /= 0】CPU里面的狀態寄存器的 Eflags的溢出標記位一直都是1,CPU里面的數據一直都是這個進程的上下文內容不會更改,所以就會一直被捕捉,被調度,就會出現死循環,并且一直在觸發8號信號。

???野指針

CR3 寄存器:保存頁表的起始地址,負責虛擬地址和物理地址轉化。

MMU【硬件】被集成在CPU內部:完成虛擬地址和物理地址轉化。

ELP:讀取可執行程序的起始地址。

當傳遞一個 0 地址,在MMU轉化出來 0,我們沒有權利訪問最低的地址0,MMU這個硬件經過 轉化或權限 方面上, 發現根本不能轉化出來這個地址,使得MMU【硬件】報錯,即CPU內部出錯【與上面的類似】,OS就會知道,OS就會向目標進程去識別,就會殺掉這個進程。也要類似 狀態寄存器的東西,轉化錯誤,所以就會死循環。

OS怎么知道我們的進程內部出錯了?程序內部的錯誤,其實都會表現在硬件錯誤上,OS就會知道是哪個地方出錯,進而給對應的目標進程發送信號。

🌠core VS Term?

Term :正常終止進程【不需要進行debug】。

Core:也是終止進程,但會多做一些處理。核心轉儲,在當前目錄下形成文件【pid.core】,OS在進程崩潰的時候,將進程在內存中的部分信息保存起來【保存在磁盤上,持久化起來】,方便后續調試!這個文件【pid.core】一般都會被云服務器關掉。

把core功能關閉的原因:在云服務器上,若野指針、除 0 出現錯誤等等,一般都會在后端立即重啟這個服務。若不關閉,當某個錯誤,一直重復 重啟后掛掉,磁盤上就會出現大量的core文件,甚至磁盤爆滿,就會影響系統 或 某些應用服務直接就掛掉,即 會因為系統問題,導致磁盤爆滿

?core 的使用 --- 調試

🌠 如果是子進程異常了呢? core 會不會出現?

子進程會不會出現core取決于:退出信號是否終止動作 && 服務器是否開啟 core 功能。

🌠小結:

? 鍵盤、系統指令、系統調用、軟件條件、異常 的信號產生,最終都要有OS來執行,因為OS是進程的管理者,統一由OS來向目標進程發信號;

? 信號的處理方式:不是立即處理,而是在合適的時候處理;

? 信號如果不是被立即處理,信號就會暫時被進程記錄下來,保存在進程對應的PCB中的信號位圖;

? 一個進程在沒有收到信號的時候,知道自己應該對合法信號作何處理:默認、忽略、自定義;

? OS向目標進程發送信號:實則是OS向目標進程寫信號。

?五、信號處理

1. 默認處理動作

void handler(int signo)
{std::cout << "get a signal: " << signo << std::endl;exit(1);
}int main()
{signal(2, SIG_DFL);// default:默認while(true){pause();}
}

2. 忽略:本身就是一種信號捕捉的方法,動作就是忽略

void handler(int signo)
{std::cout << "get a signal: " << signo << std::endl;exit(1);
}int main()
{signal(2, SIG_IGN);// 忽略(不做處理),本身就是一種信號捕捉的方法,動作就是忽略while(true){pause();}
}

?3. 自定義 捕捉一個信號

void handler(int signo)
{std::cout << "get a signal: " << signo << std::endl;exit(1);
}int main()
{// 信號捕捉:// 1. 默認// 2. 忽略// 3. 自定義::signal(2, handler);// 自定義while(true){pause();}
}

如若對你有幫助,記得關注、收藏、點贊哦~ 您的支持是我最大的動力🌹🌹🌹🌹!!!

若有誤,望各位,在評論區留言或者私信我 指點迷津!!!謝謝 ヾ(≧▽≦*)o? \( ?? ω ?? )/

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

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

相關文章

Python 網絡編程入門

目錄 一、前言 二、網絡通信基礎12&#xff1a;TCP 與 UDP 協議解析 2.1 TCP 協議&#xff1a;可靠的面向連接通信 2.2 UDP 協7議&#xff1a;無連接的快速通信 2.3 Sock12et&#xff1a;網絡通信的基石 三、TCP 編程實15戰&#xff1a;從單工通信到雙向聊天 3.1 TCP 客…

Django壓縮包形式下載文件

通過web將minio上的文件以壓縮包-文件夾-文件的形式下載到本地 import os from bx_mes import settings from io import BytesIO import zipfile from django.http import StreamingHttpResponse class FileRemote(GenericAPIView):def post(self,request):# 壓縮包名folder_n…

Enhancing Relation Extractionvia Supervised Rationale Verifcation and Feedback

Enhancing Relation Extraction via Supervised Rationale Verification and Feedback| Proceedings of the AAAI Conference on Artificial Intelligencehttps://ojs.aaai.org/index.php/AAAI/article/view/34631 1. 概述 關系抽取(RE)任務旨在抽取文本中實體之間的語義關

【RAG】ragflow源碼亮點:文檔embedding向量化加權融合

引言&#xff1a; 最近在看ragflow源碼&#xff0c;其中有一個較為巧妙地設計&#xff1a;分別將 文字 、 標題 行向量化 之后&#xff0c;直接根據權重&#xff0c;進行加法運算&#xff0c;得到向量融合&#xff0c;增強了文本向量化的表示能力&#xff0c;這里開始討論一下…

限流系列:sentinel

目錄 滑動窗口算法 Sentinel 數據模型 示例 大致流程 ???????entry ???????entryWithPriority ???????FlowSlot.entry ???????checkFlow ???????canPass ???????avgUsedTokens ???????passQps ???????pa…

Java 訪問者模式深度重構:從靜態類型到動態行為的響應式設計實踐

一、訪問者模式的本質與核心價值 在軟件開發的漫長演進中&#xff0c;設計模式始終是架構師手中的利刃。當我們面對復雜對象結構上的多種操作需求時&#xff0c;訪問者模式&#xff08;Visitor Pattern&#xff09;猶如一把精密的手術刀&#xff0c;能夠優雅地分離數據結構與作…

UE 5 C++設置物體位置和旋轉,初始化虛幻引擎樣條線、加載引用虛幻編輯器中的藍圖、設置虛幻編輯器中Actor大小

一、設置物體位置和旋轉 UE.cpp文件中代碼&#xff1a; Mesh->SetWorldLocationAndRotation(FVector(50.0f, 50.0f, 50.0f),FRotator(0,-90,0)); vs代碼編輯器中旋轉信息順序&#xff08;yzx&#xff09;&#xff1a; Pitch、 Yaw、 Roll UE編輯器中旋轉信息順序&#xf…

【文本分類】KG-HTC 知識圖譜提升分類準確率

最近看到一篇論文“KG-HTC: Integrating Knowledge Graphs into LLMs for Effective Zero-shot Hierarchical Text Classification”&#xff0c;介紹了文本分類的技巧&#xff0c;這篇文航主要利用了知識圖譜大模型的思路&#xff0c;實驗效果不錯&#xff0c;里面的一些論述也…

三大微調技術對比:Prompt/Prefix/P-Tuning

Prompt Tuning、Prefix Tuning和P - Tuning的區別 概念方面: Prompt Tuning:在輸入序列前添加可訓練的額外Token以適配下游任務,預訓練語言模型參數不變。比如在文本分類中,在句子前加特定Token如“(OPINION)”,讓模型理解是對觀點進行分類的任務。Prefix Tuning:在每層T…

14.「實用」扣子(coze)教程 | Excel文檔自動批量AI文檔生成實戰,中級開篇

隨著AI編程工具及其能力的不斷發展&#xff0c;編程將變得越來越簡單。 在這個大趨勢下&#xff0c;大師兄判斷未來的編程將真正成為像office工具一樣的辦公必備技能。每個人通過 &#xff08;專業知識/資源編程&#xff09;將自己變成一個復合型的人才&#xff0c;大大提高生…

量子-經典協同計算新路徑:NISQ 時代混合算法對后量子密碼學的適應性探索

內容來源&#xff1a;量子前哨&#xff08;ID&#xff1a;Qforepost&#xff09; 文丨浪味仙 排版丨浪味仙 行業動向&#xff1a;3700字丨10分鐘閱讀 5 月 20 日&#xff0c;由北京量子院、清華大學、數學工程與先進計算國家重點實驗室、南洋理工大學、量子信息前沿科學中心…

CentOS中安裝Docker Compose

在CentOS中安裝Docker Compose的步驟如下&#xff1a; 步驟 1&#xff1a;確保Docker已安裝 Docker Compose依賴Docker環境&#xff0c;請先安裝Docker&#xff1a; # 添加Docker官方倉庫 sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://downlo…

電商小程序店鋪詳情頁:頭部無限分類與篩選功能實現

電商小程序店鋪詳情頁:頭部無限分類與篩選功能實現 一、場景需求與技術選型二、頭部無限分類導航三、篩選功能實現:Picker多列選擇組件一、場景需求與技術選型 在電商小程序生態中,店鋪詳情頁作為用戶瀏覽商品的核心流量入口,其交互效率與功能完整性直接影響商品轉化率。傳…

Graph Neural Network(GNN)

我們首先要了解什么是圖,圖是由節點和邊組成的,邊的不一樣也導致節點的不同(參考化學有機分子中的碳原子) gnn可以處理classification的問題,也就是分類的問題 也可以處理generation的問題 借一部日劇來說明,這個日劇是講主角尋找殺害他父親的兇手的,劇中的人物有姓名和特征 …

FallbackHome的啟動流程(android11)

首次開機開機動畫播完進入Launcher桌面時黑屏進入Launcher,有黑屏不太美觀&#xff0c;在重啟以后會在進入桌面后會顯示android正在啟動等一會進入Launcher,這就是系統FallBackHome機制 接下來我們跟著代碼看下首次啟動系統如何進入FallbackHome的 在SystemServer的startOthe…

【EdgeYOLO】《EdgeYOLO: An Edge-Real-Time Object Detector》

Liu S, Zha J, Sun J, et al. EdgeYOLO: An edge-real-time object detector[C]//2023 42nd Chinese Control Conference (CCC). IEEE, 2023: 7507-7512. CCC-2023 源碼&#xff1a;https://github.com/LSH9832/edgeyolo 論文&#xff1a;https://arxiv.org/pdf/2302.07483 …

宮格導航--純血鴻蒙組件庫AUI

摘要&#xff1a; 宮格導航(A_GirdNav)&#xff1a;可設置導航數據&#xff0c;建議導航項超過16個&#xff0c;可設置“更多”圖標指向的頁面路由。最多顯示兩行&#xff0c;手機每行最多顯示4個圖標&#xff0c;折疊屏每行最多6個圖標&#xff0c;平板每行最多8個圖標。多余圖…

調試的按鈕

在Debug的時候&#xff0c;會有一些按鈕&#xff0c;我們需要知道它們各自的作用。 注&#xff1a;調試器本身并沒有一個直接的、可以撤銷已執行代碼效果的“返回上一步&#xff08;Undo Last Step&#xff09;”或“逆向執行&#xff08;Reverse Debugging&#xff09;”按鈕…

人工智能如何協助老師做課題

第一步&#xff1a;在騰訊元寶對話框中輸入如何協助老師做課題&#xff0c;通過提問&#xff0c;我們了解了老師做課題的步驟和建議。 第二步&#xff1a;開題報告提問&#xff0c;騰訊元寶對話框中&#xff0c;輸入“大單元視域下小學數學教學實踐研究課題開題報告。”......…

OpenGL Chan視頻學習-5 Vertex Attributes and Layouts in OpenGL

bilibili視頻鏈接&#xff1a; 【最好的OpenGL教程之一】https://www.bilibili.com/video/BV1MJ411u7Bc?p5&vd_source44b77bde056381262ee55e448b9b1973 一、知識點整理 1.1.OpenGL管線工作流程 為顯卡提供繪制的所有數據&#xff0c;并將數據存儲在GPU內存使用著色器&…