【linux學習】linux系統調用編程

目錄

一、任務、進程和線程

1.1任務

1.2進程

1.3線程

1.4線程和進程的關系

1.5 在linux系統下進程操作

二、Linux虛擬內存管理與stm32的真實物理內存區別

2.1 Linux虛擬內存管理

2.2?STM32的真實物理內存映射

2.3區別

三、?Linux系統調用函數 fork()、wait()、exec()

3.1 fork

3.2 wait

3.3 exec

四、在樹莓派中,創建組員賬號,完成練習

4.1 用戶創建和配置:

4.2登錄自己的樹莓派賬號練習

五、總結

一、任務、進程和線程

1.1任務

多任務系統指可以同一時間內運行多個應用程序的系統,每個應用程序被稱作一個任務。

任務是一個邏輯概念,指由一個軟件完成的任務,或者是一系列共同達到某一目的的操作。

任務的特點:

  • 在實時操作系統(RTOS)中,任務通常是獨立的、無法返回的函數。

  • 任務的調度和管理依賴于任務控制塊(TCB),它記錄任務的狀態、優先級等信息

1.2進程

進程是指一個具有獨立功能的程序在某個數據集上的一次動態執行過程,它是系統進行資源分配和調度的最小單元。

通俗來說,進程就是程序的一次執行過程,程序是靜態的,它作為系統中的一種資源是永遠存在的。而進程是動態的,它是動態的產生,變化和消亡的,擁有其自己的生命周期。

舉個例子:同時掛三個 QQ 號,它們就對應三個 QQ 進程,退出一個就會殺死一個對應的進程。但是,就算你把這三個 QQ 全都退出了,QQ 這個程序死亡了嗎?顯然沒有。

進程不僅包含正在運行的程序實體,并且包括這個運行的程序中占據的所有系統資源,比如說 CPU、內存、網絡資源等。很多小伙伴在回答進程的概念的時候,往往只會說它是一個運行的實體,而會忽略掉進程所占據的資源。比如說,同樣一個程序,同一時刻被兩次運行了,那么他們就是兩個獨立的進程。

  • 特點

    • 每個進程擁有獨立的內存空間,包括代碼段、數據段、堆和棧。

    • 進程之間相互隔離,一個進程的崩潰通常不會影響其他進程。

    • 進程是資源分配的最小單位,但不是CPU調度的最小單位。

1.3線程

線程是進程內獨立的一條運行路線,是處理器調度的最小單元,也可以稱為輕量級進程。線程——程序執行的最小單位。

  • 特點

    • 一個進程可以包含多個線程,線程共享所屬進程的內存空間和資源。

    • 線程的切換開銷較小,因為它只需要切換寄存器狀態和棧信息。

    • 線程是程序執行的最小單位,多個線程可以并發執行。

1.4線程和進程的關系

(1)一個線程只能屬于一個進程,而一個進程可以有多個線程,但至少有一個線程;

(2)資源分配給進程,同一進程內的所有線程共享該進程的所有資源;

(3)線程在執行過程中需要協作同步。不同進程中的線程之間要利用消息通信的方法實現同步;

(4)處理機分配給線程,即真正在處理機上運行的是線程;

(5)線程是進程的一個執行單元,也是進程內的可調用實體。

1.5 在linux系統下進程操作

操作:1) 用 ps -a 命令查看系統中各進程的編號pid ; 2) 用kill 命令終止一個進程pid。

ps -a
  • ps 是“process status”的縮寫,用于顯示當前系統中運行的進程信息。

  • 選項-a:表示顯示當前終端(TTY)中所有用戶啟動的進程。

我可以通過用一個sleep也來弄一個進程方便我們將他kill,如下操作:

sleep 50&
  • sleep命令用于讓當前進程暫停指定的時間(單位為秒)。這里讓進程暫停50秒。

  • &符號:將命令放到后臺執行。這樣,用戶可以在命令執行的同時繼續在終端中輸入其他命令。

kill 1317303
  • 向PID為1317303sleep進程發送終止信號,使其停止運行。

  • 再次用ps -a查看是否終止進程。

二、Linux虛擬內存管理與stm32的真實物理內存區別

2.1 Linux虛擬內存管理

Linux操作系統采用虛擬內存管理技術,使得每個進程都有各自互不干涉的進程地址空間。

在Linux中,虛擬內存管理的基本理念是“每個程序認為它擁有獨立的內存”。虛擬內存通過以下方式實現:

  • 虛擬地址與物理地址:Linux使用虛擬地址來訪問內存,這些虛擬地址通過內存管理單元(MMU)映射到物理地址。虛擬地址空間被分為用戶空間和內核空間,每個進程都有自己的虛擬地址空間。

  • 分頁機制:Linux將內存劃分為固定大小的頁面(通常是4KB),并根據需要將頁面從磁盤交換到物理內存中。這種機制允許系統運行比物理內存更大的程序。

  • 內存保護與隔離:虛擬內存機制提供了內存保護,確保一個進程無法訪問另一個進程的內存。內核空間的內存對用戶空間進程不可見。

  • 動態內存分配:Linux內核使用懶惰分配(Lazy Allocation)技術,只有當進程實際訪問分配的內存時,才會分配物理內存。

  • 交換空間(Swap):當物理內存不足時,Linux會將不常用的頁面交換到磁盤上的交換空間。

用戶感知:程序操作的是虛擬地址,物理地址對用戶透明;通過malloc()分配內存時,實際可能僅在虛擬地址空間預留范圍(brkmmap),直到訪問時才觸發缺頁異常分配物理頁。

2.2?STM32的真實物理內存映射

STM32是一種嵌入式微控制器,其內存管理相對簡單,主要基于物理內存的直接訪問。

  • 物理內存映射:STM32使用物理內存映射,將內存和外設分配到不同的地址范圍。這種映射是固定的,沒有虛擬地址的概念。

  • 內存保護缺失:STM32通常沒有內存保護機制,用戶空間代碼可以直接訪問內核空間的內存。這可能導致一個程序的錯誤操作影響整個系統。

  • 簡單的內存管理:STM32的內存管理主要依賴于靜態分配,程序在啟動時分配所需的內存,并在運行時直接訪問這些內存。

  • 無交換空間:STM32沒有交換空間的概念,所有內存操作都直接在物理內存上進行。

開發模式:程序員需手動管理內存,避免溢出。外設操作通過指針直接訪問寄存器,比如常見的:

// 直接操作STM32的GPIO寄存器
#define GPIOA_ODR (*(volatile uint32_t*)0x40020014)
GPIOA_ODR |= 0x00000001; // 設置PA0引腳為高電平

2.3區別

特性Linux虛擬內存STM32物理內存映射
地址空間虛擬地址(通過MMU轉換)物理地址(直接訪問)
硬件依賴必須支持MMU(如ARM Cortex-A系列)無MMU(如ARM Cortex-M系列)
內存隔離進程間隔離,防止非法訪問無隔離,程序可直接修改任意內存/外設
動態分配支持按需分配和交換(malloc/mmap靜態分配(鏈接腳本定義堆棧/全局變量)
訪問權限控制通過頁表實現讀/寫/執行權限無權限控制,依賴程序員自律
典型應用場景通用計算(多任務/復雜應用)實時嵌入式系統(確定性/低延遲)

三、?Linux系統調用函數 fork()、wait()、exec()

3.1 fork

在Linux 中創建一個新進程的唯一方法是使用fork()函數。fork()函數用于從已存在的一個進程中創建一個新的進程,新進程稱為子進程,而原進程稱為父進程。

  • 子進程特性

    • 子進程是父進程的復制品,繼承父進程的地址空間,包括代碼段、數據段、堆、棧等。

    • 子進程繼承父進程的文件描述符、信號控制設定、進程優先級、進程組號、當前工作目錄等。

    • 子進程擁有獨立的進程號(PID)和資源使用信息。

  • 返回值

    • 在父進程中,fork()返回子進程的PID。

    • 在子進程中,fork()返回0。

?1.在練習文件夾下面利用nano創建函數fork_example.c文件(建議也可以參考下文中樹莓派部分的fork函數,那個比較簡潔)

#include <stdio.h>      // 標準輸入輸出庫,用于printf等函數
#include <sys/types.h>  // 包含數據類型定義,如pid_t
#include <unistd.h>     // 包含fork、getpid、getppid等函數
#include <stdlib.h>     // 包含exit函數
#include <errno.h>      // 包含錯誤號定義
#include <sys/wait.h>   // 包含waitpid函數及相關宏int main() {pid_t pid;          // 定義一個pid_t類型的變量,用于存儲fork返回的進程IDint ret = 1;        // 定義一個返回值變量,未在代碼中使用int status;         // 定義一個變量,用于存儲子進程退出狀態pid = fork();       // 調用fork函數創建一個子進程if (pid == -1) {    // 如果fork返回-1,表示創建子進程失敗printf("can't fork, error occured\n");  // 輸出錯誤信息exit(EXIT_FAILURE);  // 退出程序,返回值為EXIT_FAILURE} else if (pid == 0) {  // 如果fork返回0,表示當前是子進程printf("child process, pid = %u\n", getpid());  // 輸出子進程的PIDprintf("parent of child process, pid = %u\n", getppid());  // 輸出子進程的父進程PIDchar *argv_list[] = {"ls", "-lart", "/home", NULL};  // 定義一個字符串數組,作為execv的參數// 調用execv替換當前進程映像為"ls"程序,并傳遞參數"-lart"和"/home"execv("ls", argv_list);  // 如果execv成功,控制權將轉移到"ls"程序,不會返回到這里// 如果execv失敗,返回-1,并繼續執行下面的代碼exit(0);  // 子進程退出} else {  // 如果fork返回一個正數,表示當前是父進程,返回值是子進程的PIDprintf("Parent of parent process, pid = %u\n", getppid());  // 輸出父進程的父進程PIDprintf("parent process, pid = %u\n", getpid());  // 輸出父進程的PID// 父進程調用waitpid等待子進程結束if (waitpid(pid, &status, 0) > 0) {  // 如果waitpid成功,返回子進程的PID// 檢查子進程是否正常退出if (WIFEXITED(status) && !WEXITSTATUS(status))  // 如果子進程正常退出且返回值為0printf("program execution successful\n");else if (WIFEXITED(status) && WEXITSTATUS(status)) {  // 如果子進程正常退出但返回值非0if (WEXITSTATUS(status) == 127) {  // 如果返回值為127,表示execv失敗printf("execv failed\n");} else  // 如果返回值非127,表示程序執行完成但返回了非零狀態printf("program terminated normally, but returned a non-zero status\n");} else  // 如果子進程沒有正常退出printf("program didn't terminate normally\n");} else {  // 如果waitpid失敗printf("waitpid() failed\n");}exit(0);  // 父進程退出}return 0;  // 程序正常結束返回0
}

2.使用cmake編譯fork_example.c在根目錄下創建(想著用不同的方法來編譯,掌握多種編譯辦法。也可以直接采用下文的gcc方式來編譯)

CMakeLists.txt

cmake_minimum_required(VERSION 3.10)  # 最低 CMake 版本要求
project(Fork_demo)                     # 項目名稱# 添加可執行文件
add_executable(fork_demo fork_example.c)# 設置 C 標準(可選)
set(CMAKE_C_STANDARD 11)

3.構建目錄生成文件

mkdir build && cd build

創建構建目錄并生成 Makefile

cmake --build build
./build/fork_demo

運行即可,結果如圖:

3.2 wait

功能:wait()函數用于使父進程(也就是調用wait()的進程)阻塞,直到一個子進程結束或者該進程接收到了一個指定的信號為止。如果該父進程沒有子進程或者它的子進程已經結束,則wait()函數就會立即返回。

  • 作用

    • 確保父進程在子進程結束后再繼續執行。

    • 防止子進程變成僵尸進程(zombie process)。

  • 返回值

    • 如果父進程沒有子進程或者子進程已經結束,wait()會立即返回。

    • 返回值是子進程的PID。

?wait調用:

1.創建一個?fork_wait.c?文件,內容如下:

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>  // 必須包含此頭文件以使用 wait()int main() {pid_t pid = fork();if (pid < 0) {perror("fork 失敗");return 1;} else if (pid == 0) {// 子進程執行任務printf("子進程 PID = %d\n", getpid());sleep(2);  // 模擬耗時操作printf("子進程結束\n");} else {// 父進程等待子進程結束printf("父進程 PID = %d,等待子進程 %d...\n", getpid(), pid);int status;wait(&status);  // 阻塞等待子進程結束printf("子進程退出狀態: %d\n", WEXITSTATUS(status));}return 0;
}

同樣的創建Makefile,

# 定義編譯器和編譯選項
CC = gcc
CFLAGS = -Wall -Wextra -std=c11# 定義目標可執行文件名和源文件
TARGET = fork_wait_demo
SRC = fork_wait.c# 默認目標
all: $(TARGET)# 編譯規則
$(TARGET): $(SRC)$(CC) $(CFLAGS) -o $@ $^# 清理生成的文件
clean:rm -f $(TARGET)# 偽目標聲明(避免與同名文件沖突)
.PHONY: all clean

編譯運行效果:

make
./fork_wait_demo

結果演示:

3.3 exec

在Linux 中使用exec函數族主要有兩種情況:
1.當進程認為自己不能再為系統和用戶做出任何貢獻時,他就可以發揮最后一點余熱,調用任何一個exec,讓自己以新的面貌重生;
2.如果一個進程想執行另一個程序,那么它就可以調用fork() 函數新建一個進程,然后調用exec 函數族中的任意一個函數,這樣看起來就像通過執行應用程序而產生了一個新進程(這種情況非常普遍)。

exec調用:

可以先建一個文件夾哈(這樣方便看到保存每個函數的那個記錄,我上面兩個函數忘記創建了,之后做實驗最好一個實驗一個文件夾,這樣清爽一些)

mkdir exec && cd exec

1.創建?fork_exec.c?文件,參考代碼:

#include <stdio.h>
#include <unistd.h>int main() {pid_t pid = fork();if (pid == 0) {// 子進程執行 ls -lexecl("/bin/ls", "ls", "-l", NULL);perror("exec failed"); // 若 exec 失敗才會執行return 1;}return 0;
}

2.可以用gcc或者make或者cmake等方式來進行編譯,我們這里就用常規簡單一點的gcc(cmake和make的方式上面兩個函數都有代碼,修改一下名稱就可以用啦)

gcc fork_exec.c -o fork_demo
./fork_demo

結果演示:

四、在樹莓派中,創建組員賬號,完成練習

4.1 用戶創建和配置:

提前進入到主要的賬號里邊給各個用戶加上相關的權限,操作如下(putty和Xterminal都可以)

1.使用adduser命令創建用戶

sudo adduser zsc
  • 執行后會提示設置密碼及用戶信息(非必填項可直接回車跳過)

  • 默認自動生成同名主目錄?/home/username

2.配置用戶權限

1.將用戶加入sudo組

sudo usermod -aG sudo zsc

2.加入常用硬件訪問組

sudo usermod -aG adm,dialout,plugdev zsc

3.?驗證用戶權限

id zsc  # 查看用戶所屬組
groups zsc  # 列出用戶所有附加組

4.2登錄自己的樹莓派賬號練習

在Xterminal中利用ssh連接登陸上自己的樹莓派賬號。(連接過程和之前的博客步驟一樣的,通過電腦移動熱點查詢物理地址,賬號密碼確認后即可登錄)

我們還可以查看樹莓派下面的其他用戶

compgen -u

進入到自己的樹莓派環境中

配置一下安裝一下環境:

在樹莓派Ubuntu系統中,默認可能未安裝GCC,安裝GCC及編譯所需的工具鏈(如makeg++等)

sudo apt update
sudo apt install build-essential

1.創建并打開目錄

mkdir test0404 && cd test0404

2.編寫fork.c程序(選用gcc的方式來編譯啦,這樣快捷一些)

nano fork_gcc.c

簡單的編寫一個代碼:

#include <stdio.h>
#include <unistd.h>int main() {pid_t pid = fork();if (pid < 0) {fprintf(stderr, "Fork失敗\n");return 1;} else if (pid == 0) {printf("子進程ID: %d\n", getpid());} else {printf("父進程ID: %d,子進程ID: %d\n", getpid(), pid);}return 0;
}

3.編譯并運行:

gcc fork_gcc.c -o fork_gcc//編譯需要卡一會./fork_gcc

五、總結

通過本次讓我收獲很大很大,本文主要闡述了任務、進程、線程的定義,區別和聯系,參考文獻1中有更加直白易懂的說法(感興趣的可以去看看),同時通過查閱資料闡述了虛擬機內存管理和STM32的物理內存中的一些差別,進一步了解虛擬機和存儲的方式;最后也是本次最重要的實踐環節,學習調用了fork、wait、exec函數,深入理解了每個函數在樹莓派的中是如何使用的,同時每個函數的調用用了不同的編譯方法(cmake、make、gcc)(個人建議設計內容少的函數可以直接用gcc是最方便的),加深了對Ubuntu的運用和理解,同時通過反反復復的敲代碼和命令,對整體的編程水平還是上升了不少,感興趣的朋友也可以自己試試手敲,收獲會很大的。

樹莓派的操作也越來越熟悉了,在XTerminal很好用,建議用這個,很不錯。

本文中原理部分有些圖片來源于網絡,如有侵權請及時與我聯系刪除,本人才疏學淺,如有描述不準確或出錯的地方還請海涵,感謝您的閱讀!

參考文獻:

https://zhuanlan.zhihu.com/p/391496775

https://zhuanlan.zhihu.com/p/403313422

Linux系統調用編程-CSDN博客

Linux Ubuntu 入門基本命令整理_linux ubuntu入門基本命令整理-CSDN博客

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

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

相關文章

react redux的學習,多個reducer

redux系列文章目錄 第一章 簡單學習redux,單個reducer 前言 前面我們學習到的是單reducer的使用&#xff1b;要知道redux是個很強大的狀態存儲庫&#xff0c;可以支持多個reducer的使用。 combineReducers ?combineReducers?是Redux中的一個輔助函數&#xff0c;主要用于…

Oracle數據庫數據編程SQL<3.5 PL/SQL 存儲過程(Procedure)>

存儲過程(Stored Procedure)是 Oracle 數據庫中一組預編譯的 PL/SQL 語句集合,存儲在數據庫中并可通過名稱調用執行。它們是企業級數據庫應用開發的核心組件。 目錄 一、存儲過程基礎 1. 存儲過程特點 2. 創建基本語法 3. 存儲過程優點 4. 簡單示例 二、沒有參數的存儲…

手撕AVL樹

引入&#xff1a;為何要有AVL樹&#xff0c;二次搜索樹有什么不足&#xff1f; 二叉搜索樹有其自身的缺陷&#xff0c;假如往樹中插入的元素有序或者接近有序&#xff0c;二叉搜索樹就會退化成單支樹&#xff0c;時間復雜度會退化成O(N)&#xff0c;因此產生了AVL樹&#xff0c…

《 C語言中的變長數組:靈活而強大的特性》

&#x1f680;個人主頁&#xff1a;BabyZZの秘密日記 &#x1f4d6;收入專欄&#xff1a;C語言 &#x1f30d;文章目入 一、變長數組的定義二、變長數組的優勢三、變長數組的使用示例示例1&#xff1a;動態輸入數組大小示例2&#xff1a;變長數組在函數中的應用 四、變長數組的…

【微服務】基礎概念

1.什么是微服務 微服務其實就是一種架構風格&#xff0c;他提倡我們在開發的時候&#xff0c;一個應用應該是一組小型服務而組成的&#xff0c;每一個服務都運行在自己的進程中&#xff0c;每一個小服務都通過HTTP的方式進行互通。他更加強調服務的徹底拆分。他并不是僅局限于…

Linux make與makefile 項目自動化構建工具

本文章將對make與makefile進行一些基礎的講解。 假設我們要建造一座房子&#xff0c;建造過程涉及很多步驟&#xff0c;比如打地基、砌墻、安裝門窗、粉刷墻壁等。每個步驟都有先后順序&#xff0c;并且有些步驟可能依賴于其他步驟的完成。比如&#xff0c;你必須先打好地基才…

如何判斷多個點組成的3維面不是平的,如果不是平的,如何拆分成多個平面

判斷和拆分三維非平面為多個平面 要判斷多個三維點組成的面是否為平面&#xff0c;以及如何將非平面拆分為多個平面&#xff0c;可以按照以下步驟進行&#xff1a; 判斷是否為平面 平面方程法&#xff1a; 選擇三個不共線的點計算平面方程&#xff1a;Ax By Cz D 0檢查其…

多layout 布局適配

安卓多布局文件適配方案操作流程 以下為通過多套布局文件適配不同屏幕尺寸/密度的詳細步驟&#xff0c;結合主流適配策略及最佳實踐總結&#xff1a; 一、?創建多套布局資源目錄? ?按屏幕尺寸劃分? 在 res 目錄下創建以下文件夾&#xff08;根據設備特性自動匹配&#xff…

Java 大視界 -- Java 大數據在智能農業無人機植保作業路徑規劃與藥效評估中的應用(165)

&#x1f496;親愛的朋友們&#xff0c;熱烈歡迎來到 青云交的博客&#xff01;能與諸位在此相逢&#xff0c;我倍感榮幸。在這飛速更迭的時代&#xff0c;我們都渴望一方心靈凈土&#xff0c;而 我的博客 正是這樣溫暖的所在。這里為你呈上趣味與實用兼具的知識&#xff0c;也…

美關稅加征下,Odoo免費開源ERP如何助企業破局?

近期&#xff0c;美國特朗普政府推行的關稅政策對全球供應鏈和進出口企業造成巨大沖擊&#xff0c;尤其是依賴中美貿易的企業面臨成本激增、利潤壓縮和合規風險。在此背景下&#xff0c;如何通過數字化轉型優化管理效率、降低運營成本成為企業生存的關鍵。本文以免費開源ERP系統…

go游戲后端開發25:紅中麻將規則介紹

一、游戲基礎規則介紹 在開發紅中麻將游戲之前&#xff0c;我們需要先了解其基礎規則。紅中麻將的牌面由 a、b、c、d 四種花色組成&#xff0c;其中 a、b、c 分別代表萬、條、筒&#xff0c;每種花色都有 1 - 9 的九種牌&#xff0c;每種牌各有四張&#xff0c;總計 36 張 4 …

Unity:平滑輸入(Input.GetAxis)

目錄 1.為什么需要Input.GetAxis&#xff1f; 2. Input.GetAxis的基本功能 3. Input.GetAxis的工作原理 4. 常用參數和設置 5. 代碼示例&#xff1a;用GetAxis控制角色移動 6. 與Input.GetAxisRaw的區別 7.如何優化GetAxis&#xff1f; 1.為什么需要Input.GetAxis&…

OpenCV:計算機視覺的強大開源庫

文章目錄 引言一、什么是OpenCV&#xff1f;1.OpenCV的核心特點 二、OpenCV的主要功能模塊1. 核心功能&#xff08;Core Functionality&#xff09;2. 圖像處理&#xff08;Image Processing&#xff09;3. 特征檢測與描述&#xff08;Features2D&#xff09;4. 目標檢測&#…

AI浪潮下的IT職業轉型:醫藥流通行業傳統IT顧問的深度思考

AI浪潮下的IT職業轉型&#xff1a;醫藥流通行業傳統IT顧問的深度思考 一、AI重構IT行業的技術邏輯與實踐路徑 1.1 醫藥流通領域的智能辦公革命 在醫藥批發企業的日常運營中&#xff0c;傳統IT工具正經歷顛覆性變革。以訂單處理系統為例&#xff0c;某醫藥集團引入AI智能客服…

Qt進階開發:QFileSystemModel的使用

文章目錄 一、QFileSystemModel的基本介紹二、QFileSystemModel的基本使用2.1 在 QTreeView 中使用2.2 在 QListView 中使用2.3 在 QTableView 中使用 三、QFileSystemModel的常用API3.1 設置根目錄3.2 過濾文件3.2.1 僅顯示文件3.2.2 只顯示特定后綴的文件3.2.3 只顯示目錄 四…

KAPC的前世今生--(下)下RPCRT4!NMP_SyncSendRecv函數分析

第一部分&#xff1a;nt!KiDeliverApc函數調用nt!IopCompleteRequest函數后準備返回 1: kd> kv # ChildEBP RetAddr Args to Child 00 ba3eec18 80a3c83b 896e4e40 ba3eec64 ba3eec58 nt!IopCompleteRequest0x3a3 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv…

深入理解C++引用:從基礎到現代編程實踐

一、引用的本質與基本特性 1.1 引用定義 引用是為現有變量創建的別名&#xff0c;通過&符號聲明。其核心特點&#xff1a; 必須初始化且不能重新綁定 與被引用變量共享內存地址 無獨立存儲空間&#xff08;編譯器實現&#xff09; 類型必須嚴格匹配 int value 42; in…

嵌入式Linux開發環境搭建,三種方式:虛擬機、物理機、WSL

目錄 總結寫前面一、Linux虛擬機1 安裝VMware、ubuntu18.042 換源3 改中文4 中文輸入法5 永不息屏6 設置 root 密碼7 安裝 terminator8 安裝 htop&#xff08;升級版top&#xff09;9 安裝 Vim10 靜態IP-虛擬機ubuntu11 安裝 ssh12 安裝 MobaXterm &#xff08;SSH&#xff09;…

軟件工程面試題(二十七)

1、j a v a 對象初始化順序 1.類的初始化(initialization class & interface) 2.對象的創建(creation of new class instances) 順序:應為類的加載肯定是第一步的,所以類的初始化在前。大體的初始化順序是: 類初始化 -> 子類構造函數 -> 父類構造函數 -&g…

《AI大模型開發筆記》MCP快速入門實戰(一)

目錄 1. MCP入門介紹 2. Function calling技術回顧 3. 大模型Agent開發技術體系回顧 二、 MCP客戶端Client開發流程 1. uv工具入門使用指南 1.1 uv入門介紹 1.2 uv安裝流程 1.3 uv的基本用法介紹 2.MCP極簡客戶端搭建流程 2.1 創建 MCP 客戶端項目 2.2 創建MCP客戶端…