linux學習:進程

目錄

例子1? ??獲取當前進程的進程標識符

例子2? ?創建一個新的子進程

例子3? ??展示了父進程和子進程的進程標識符

例子4? ? ?區分父進程和子進程

例子5? ? ?區分父進程和子進程的行為

例子6? ??比較進程標識符來區分父進程和子進程

例子7? ? ?子進程如何修改一個變量,對父進程的影響

例子8? ? ?子進程創建并循環執行,每隔3秒打印一條消息

例子9? ??父進程和子進程分別進入循環,每隔一秒打印一條消息

例子10? ? ?vfork()創建子進程

例子11? ??vfork() 創建子進程,執行一定次數后會自行退出

例子12? ??

例子13? ??創建子進程,父子不同的操作。子在一定條件下會自行退出

例子14? ? 父等待子進程結束后繼續執行

例子15? ??wait() 父等待子結束,父打印子進程的退出狀態

例子16? ?waitpid替代 wait檢查子狀態,waitpid允許父進程進行非阻塞檢查或等待特定的子進程結束

例子17? ?子在一定條件下會自行退出,而父進程僅打印一次信息

例子18? ?execl執行一個新的程序。這個函數屬于 exec 系列函數,它們用于替換當前進程的映像

例子19? ??execl函數來執行 /bin/ls 命令,通常用于列出目錄內容。如果 execl() 調用成功,則不會返回;如果調用失敗,會返回 -1 并打印錯誤信息

例子20? ??execl函數來執行 /bin/ls 命令,配上 -l 選項來以長格式列出目錄內容。如果 execl() 調用成功,則會替換當前進程的映像并不返回;如果失敗,會返回 -1 并打印錯誤信息

例子21? ??execl()執行系統命令 /bin/date,該命令用于顯示當前系統日期和時間。如果 execl()調用成功,它會替換當前進程的映像為 /bin/date 并不返回;如果失敗,會返回 -1 并打印錯誤信息

例子22? ??execlp()執行系統命令 ps,該命令用于顯示當前系統的進程狀態。如果 execlp() 調用成功,它會替換當前進程的映像為 ps 命令并不返回;如果失敗,會返回 -1 并打印錯誤信息

例子23? ??execvp()執行系統命令 ps,用于顯示當前系統的進程狀態。execvp() 類似于 execlp(),但允許通過一個參數數組來傳遞命令和其參數。如果 execvp() 調用成功,它會替換當前進程的映像為 ps 命令并不返回;如果失敗,會返回 -1 并打印錯誤信息

例子24? ??execv()執行 /bin/ps 命令,該命令用于顯示當前系統的進程狀態。execv() 類似于 execl(),但使用數組來傳遞命令和其參數。如果 execv() 調用成功,它會替換當前進程的映像為 /bin/ps 并不返回;如果失敗,會返回 -1 并打印錯誤信息

例子25? 輸入來觸發文件操作,在子進程中進行。這個例子特別是在輸入為 1 時,程序會修改配置文件 config.txt 中的一個特定值

例子26? ??根據輸入決定是否創建一個子進程來執行特定的程序 (changData),該程序預期對 config.txt 文件進行修改。如果輸入不是 1,則打印消息并繼續等待

例子27? ? 根據輸入決定執行一個外部命令(changData),該命令與配置文件 config.txt 相關聯。如果用戶輸入 1,程序會創建一個子進程,該子進程通過 system 函數調用外部程序 ./changData 來處理文件 config.txt

例子28? ??system() 執行系統命令(在本例中是 ps),這個命令用來列出當前運行的進程。然而,該代碼示例存在一個問題:它沒有捕獲 system() 調用的輸出

例子29? ?popen() 和 fread() 函數從 ps 命令獲取輸出并將其讀入到一個字符數組中。該程序展示了如何執行系統命令并捕獲其輸出,適合需要從命令行工具中直接讀取數據的場景

例子30? ?處理命令行參數。它通過遍歷 argc 和 argv 數組來打印所有傳遞給程序的參數

例子31? ?等待用戶輸入。當用戶輸入 1 時,程序會創建一個子進程,這個子進程會修改一個文件(./file1)中特定字符串("LENG=")之后的字符

例子32? ??execl()函數是為了替換當前的進程映像為/bin/ls命令的進程映像

例子33? ?vfork()創建子進程并控制執行順序


例子1? ??獲取當前進程的進程標識符

#include <stdio.h>   // 引入標準輸入輸出庫,用于打印
#include <sys/types.h> // 引入數據類型,包括 pid_t
#include <unistd.h>    // 引入 POSIX 操作系統API,包括 getpid()int main()
{pid_t pid;  // 定義進程標識符變量pid = getpid(); // 調用getpid()函數獲取當前進程的PIDprintf("my pid is %d\n", pid);  // 打印當前進程的PIDwhile(1);  // 使程序進入無限循環,防止程序立即結束return 0;  // 正常情況下,程序不會執行到這里,因為上面有無限循環
}

例子2? ?創建一個新的子進程

#include <stdio.h>   // 引入標準輸入輸出庫,用于打印
#include <sys/types.h> // 引入數據類型,包括 pid_t
#include <unistd.h>    // 引入 POSIX 操作系統API,包括 getpid() 和 fork()int main()
{pid_t pid;  // 定義進程標識符變量pid = getpid(); // 調用getpid()函數獲取當前進程的PIDfork(); // 調用fork()創建一個子進程。父進程中,fork返回新創建的子進程的PID;在子進程中,fork返回0。printf("my pid is %d\n", pid);  // 打印當前進程的PID,注意這里將在父進程和子進程中都執行。return 0;  // 結束程序,父進程和子進程都會到達這里并退出
}

例子3? ??展示了父進程和子進程的進程標識符

#include <stdio.h>   // 引入標準輸入輸出庫,用于打印
#include <sys/types.h> // 引入數據類型,包括 pid_t
#include <unistd.h>    // 引入 POSIX 操作系統API,包括 getpid() 和 fork()int main()
{pid_t pid;  // 定義進程標識符變量pid = getpid(); // 調用getpid()函數獲取當前進程的PIDfork(); // 調用fork()創建一個子進程。父進程中,fork返回新創建的子進程的PID;在子進程中,fork返回0。// 在printf中顯示初始進程的PID和當前進程的PID。// "pid" 是調用fork()之前的父進程的PID。// "getpid()" 將獲取當前進程的PID,這在父進程和子進程中可能不同。printf("my pid is %d, current pro id:%d\n", pid, getpid());return 0;  // 結束程序,父進程和子進程都會到達這里并退出
}

例子4? ? ?區分父進程和子進程

#include <stdio.h>   // 引入標準輸入輸出庫,用于打印
#include <sys/types.h> // 引入數據類型,包括 pid_t
#include <unistd.h>    // 引入 POSIX 操作系統API,包括 getpid() 和 fork()int main()
{pid_t pid;  // 定義一個pid_t類型變量來存儲原始進程的PIDpid_t pid2; // 定義另一個pid_t類型變量來存儲fork后的進程PIDpid = getpid(); // 獲取并存儲當前進程的PIDprintf("before fork: pid = %d\n", pid); // 打印fork前的PIDfork(); // 創建一個新的子進程。父進程中,fork返回子進程的PID;子進程中,fork返回0。pid2 = getpid(); // 獲取fork后當前進程的PIDprintf("after fork: pid = %d\n", pid2); // 打印fork后的PIDif(pid == pid2){// 如果fork前后的PID相同,說明代碼在父進程中執行printf("this is father print\n");}else{// 如果fork前后的PID不同,說明代碼在子進程中執行printf("this is child print, child pid = %d\n", getpid());}return 0;  // 程序結束,父子進程都將執行到此處并退出
}

例子5? ? ?區分父進程和子進程的行為

#include <stdio.h>   // 引入標準輸入輸出庫,用于打印
#include <sys/types.h> // 引入數據類型,包括 pid_t
#include <unistd.h>    // 引入 POSIX 操作系統API,包括 getpid() 和 fork()int main()
{pid_t pid; // 定義一個pid_t類型變量來存儲fork()的返回值// 打印當前進程的PID,此時為父進程printf("father: id=%d\n", getpid());pid = fork(); // 調用fork()來創建一個新的子進程if (pid > 0){// 如果pid大于0,說明是父進程執行的代碼塊// 在父進程中,fork()返回創建的子進程的PIDprintf("this is father print, pid = %d\n", getpid());}else if (pid == 0){// 如果pid等于0,說明是子進程執行的代碼塊// 在子進程中,fork()返回0printf("this is child print, child pid = %d\n", getpid());}// 兩個進程都將執行到這里,并結束程序return 0;
}

例子6? ??比較進程標識符來區分父進程和子進程

#include <stdio.h>   // 引入標準輸入輸出庫,用于打印
#include <sys/types.h> // 引入數據類型,包括 pid_t
#include <unistd.h>    // 引入 POSIX 操作系統API,包括 getpid() 和 fork()int main()
{pid_t pid;     // 定義一個pid_t類型變量來存儲原始進程的PIDpid_t pid2;    // 定義另一個pid_t類型變量來存儲fork后的進程PIDpid_t retpid;  // 定義一個pid_t類型變量來存儲fork()的返回值pid = getpid(); // 獲取并存儲當前進程的PIDprintf("before fork: pid = %d\n", pid); // 打印fork前的PIDretpid = fork(); // 創建一個新的子進程。父進程中,fork返回子進程的PID;在子進程中,fork返回0。pid2 = getpid(); // 獲取fork后當前進程的PIDprintf("after fork: pid = %d\n", pid2); // 打印fork后的PIDif(pid == pid2){// 如果fork前后的PID相同,說明代碼在父進程中執行// retpid將是子進程的PID,因為在父進程中,fork()返回子進程的PIDprintf("this is father print: iretpid = %d\n", retpid);}else{// 如果fork前后的PID不同,說明代碼在子進程中執行// 在子進程中,fork()返回0printf("this is child print, retpid=%d, child pid = %d\n", retpid, getpid());}return 0;  // 程序結束,父子進程都將執行到此處并退出
}

例子7? ? ?子進程如何修改一個變量,對父進程的影響

#include <stdio.h>   // 引入標準輸入輸出庫,用于打印
#include <sys/types.h> // 引入數據類型,包括 pid_t
#include <unistd.h>    // 引入 POSIX 操作系統API,包括 getpid() 和 fork()int main()
{pid_t pid; // 定義一個pid_t類型變量來存儲fork()的返回值int data = 10; // 定義一個整型變量data,并初始化為10// 打印當前進程的PID,此時為父進程printf("father: id=%d\n", getpid());pid = fork(); // 調用fork()來創建一個新的子進程if (pid > 0){// 如果pid大于0,說明是父進程執行的代碼塊// 在父進程中,fork()返回創建的子進程的PIDprintf("this is father print, pid = %d\n", getpid());}else if (pid == 0){// 如果pid等于0,說明是子進程執行的代碼塊// 在子進程中,fork()返回0printf("this is child print, child pid = %d\n", getpid());// 子進程中修改data變量data = data + 100; // 將data加100}// 在父進程和子進程中都將執行到這里,并打印data的值printf("data=%d\n", data);return 0; // 程序結束,父子進程都將執行到此處并退出
}

例子8? ? ?子進程創建并循環執行,每隔3秒打印一條消息

#include <stdio.h>   // 引入標準輸入輸出庫,用于打印和輸入
#include <sys/types.h> // 引入數據類型,包括 pid_t
#include <unistd.h>    // 引入 POSIX 操作系統API,包括 getpid(), fork() 和 sleep()int main()
{pid_t pid; // 定義一個pid_t類型變量來存儲fork()的返回值int data = 10; // 定義一個整型變量data,并初始化為10while(1) { // 無限循環printf("please input a data\n"); // 提示用戶輸入數據scanf("%d", &data); // 從標準輸入讀取一個整數到變量dataif(data == 1) { // 如果輸入的數據是1pid = fork(); // 調用fork()來創建一個新的子進程if(pid > 0) {// 如果pid大于0,說明是父進程執行的代碼塊// 父進程不進行任何操作,繼續循環等待新的輸入}else if(pid == 0) {// 如果pid等于0,說明是子進程執行的代碼塊// 在子進程中,fork()返回0while(1) {// 子進程進入另一個無限循環,每隔3秒打印一次消息printf("do net request, pid=%d\n", getpid()); // 打印當前子進程的PIDsleep(3); // 使子進程休眠3秒}}}else {// 如果輸入的數據不是1printf("wait, do nothing\n"); // 打印等待信息}}return 0; // 程序理論上不會到達這里,因為有無限循環
}

例子9? ??父進程和子進程分別進入循環,每隔一秒打印一條消息

#include <stdio.h>    // 引入標準輸入輸出庫,用于打印
#include <sys/types.h> // 引入數據類型,包括 pid_t
#include <unistd.h>    // 引入 POSIX 操作系統API,包括 getpid(), fork() 和 sleep()int main()
{pid_t pid; // 定義一個pid_t類型變量來存儲fork()的返回值pid = fork(); // 調用fork()來創建一個新的子進程if (pid > 0){// 如果pid大于0,說明是父進程執行的代碼塊// 父進程進入一個無限循環while (1) {printf("this is father print, pid = %d\n", getpid()); // 打印父進程的信息和PIDsleep(1); // 父進程休眠1秒,減緩循環速度,防止過快消耗系統資源}    }else if (pid == 0) {// 如果pid等于0,說明是子進程執行的代碼塊// 子進程進入一個無限循環while (1) {printf("this is child print, pid = %d\n", getpid()); // 打印子進程的信息和PIDsleep(1); // 子進程休眠1秒,同樣為了減緩循環速度}    }return 0; // 程序理論上不會到達這里,因為父子進程都被設置在無限循環中
}

例子10? ? ?vfork()創建子進程

#include <stdio.h>    // 引入標準輸入輸出庫,用于打印
#include <sys/types.h> // 引入數據類型,包括 pid_t
#include <unistd.h>    // 引入 POSIX 操作系統API,包括 getpid(), vfork() 和 sleep()int main()
{pid_t pid; // 定義一個pid_t類型變量來存儲vfork()的返回值pid = vfork(); // 調用vfork()來創建一個新的子進程if (pid > 0){// 如果pid大于0,說明是父進程執行的代碼塊// 父進程進入一個無限循環while (1) {printf("this is father print, pid = %d\n", getpid()); // 打印父進程的信息和PIDsleep(1); // 父進程休眠1秒,減緩循環速度,防止過快消耗系統資源}    }else if (pid == 0) {// 如果pid等于0,說明是子進程執行的代碼塊// 子進程進入一個無限循環while (1) {printf("this is child print, pid = %d\n", getpid()); // 打印子進程的信息和PIDsleep(1); // 子進程休眠1秒,同樣為了減緩循環速度}    }return 0; // 程序理論上不會到達這里,因為父子進程都被設置在無限循環中
}

例子11? ??vfork() 創建子進程,執行一定次數后會自行退出

#include <stdio.h>    // 引入標準輸入輸出庫,用于打印
#include <sys/types.h> // 引入數據類型,包括 pid_t
#include <unistd.h>    // 引入 POSIX 操作系統API,包括 getpid(), vfork() 和 sleep()
#include <stdlib.h>    // 引入標準庫,用于 exit()int main()
{pid_t pid; // 定義一個pid_t類型變量來存儲vfork()的返回值int cnt = 0; // 定義并初始化計數器pid = vfork(); // 調用vfork()來創建一個新的子進程if (pid > 0){// 如果pid大于0,說明是父進程執行的代碼塊// 父進程進入一個無限循環while (1) {printf("cnt=%d\n", cnt); // 打印父進程中的計數器值printf("this is father print, pid = %d\n", getpid()); // 打印父進程的信息和PIDsleep(1); // 父進程休眠1秒,減緩循環速度}    }else if (pid == 0) {// 如果pid等于0,說明是子進程執行的代碼塊// 子進程進入一個無限循環while (1) {printf("this is child print, pid = %d\n", getpid()); // 打印子進程的信息和PIDsleep(1); // 子進程休眠1秒cnt++; // 子進程中的計數器增加if (cnt == 3) {exit(0); // 當計數器達到3時,子進程退出break;   // 退出循環}}    }return 0; // 程序理論上不會到達這里,因為父子進程都被設置在無限循環中
}

例子12? ??

例子13? ??創建子進程,父子不同的操作。子在一定條件下會自行退出

#include <stdio.h>    // 引入標準輸入輸出庫,用于打印
#include <sys/types.h> // 引入數據類型,包括 pid_t
#include <unistd.h>    // 引入 POSIX 操作系統API,包括 getpid(), fork() 和 sleep()
#include <stdlib.h>    // 引入標準庫,用于 exit()int main()
{pid_t pid; // 定義一個pid_t類型變量來存儲fork()的返回值int cnt = 0; // 定義并初始化計數器pid = fork(); // 調用fork()來創建一個新的子進程if (pid > 0){// 如果pid大于0,說明是父進程執行的代碼塊// 父進程進入一個無限循環while (1) {printf("cnt=%d\n", cnt); // 打印父進程中的計數器值printf("this is father print, pid = %d\n", getpid()); // 打印父進程的信息和PIDsleep(1); // 父進程休眠1秒,減緩循環速度}    }else if (pid == 0) {// 如果pid等于0,說明是子進程執行的代碼塊// 子進程進入一個無限循環while (1) {printf("this is child print, pid = %d\n", getpid()); // 打印子進程的信息和PIDsleep(1); // 子進程休眠1秒cnt++; // 子進程中的計數器增加if (cnt == 5) {exit(0); // 當計數器達到5時,子進程退出}}    }return 0; // 程序理論上不會到達這里,因為父子進程都被設置在無限循環中
}

例子14? ? 父等待子進程結束后繼續執行

#include <stdio.h>    // 引入標準輸入輸出庫,用于打印
#include <sys/types.h> // 引入數據類型,包括 pid_t
#include <unistd.h>    // 引入 POSIX 操作系統API,包括 getpid(), fork() 和 sleep()
#include <stdlib.h>    // 引入標準庫,用于 exit()
#include <sys/wait.h>  // 引入 wait() 函數需要的庫int main()
{pid_t pid; // 定義一個pid_t類型變量來存儲fork()的返回值int cnt = 0; // 定義并初始化計數器pid = fork(); // 調用fork()來創建一個新的子進程if (pid > 0){// 如果pid大于0,說明是父進程執行的代碼塊wait(NULL);  // 父進程等待任何子進程結束,這里不關心子進程的退出狀態// 父進程在子進程結束后繼續執行while (1) {printf("cnt=%d\n", cnt); // 打印父進程中的計數器值printf("this is father print, pid = %d\n", getpid()); // 打印父進程的信息和PIDsleep(1); // 父進程休眠1秒,減緩循環速度}    }else if (pid == 0) {// 如果pid等于0,說明是子進程執行的代碼塊// 子進程進入一個無限循環while (1) {printf("this is child print, pid = %d\n", getpid()); // 打印子進程的信息和PIDsleep(1); // 子進程休眠1秒cnt++; // 子進程中的計數器增加if (cnt == 5) {exit(0); // 當計數器達到5時,子進程退出}}    }return 0; // 程序理論上不會到達這里,因為父子進程都被設置在無限循環中
}

例子15? ??wait() 父等待子結束,父打印子進程的退出狀態

#include <stdio.h>    // 引入標準輸入輸出庫,用于打印
#include <sys/types.h> // 引入數據類型,包括 pid_t
#include <unistd.h>    // 引入 POSIX 操作系統API,包括 getpid(), fork() 和 sleep()
#include <stdlib.h>    // 引入標準庫,用于 exit()
#include <sys/wait.h>  // 引入 wait() 函數所需的庫int main()
{pid_t pid; // 定義一個pid_t類型變量來存儲fork()的返回值int cnt = 0; // 定義并初始化計數器int status = 10; // 定義一個整數來存儲子進程的退出狀態pid = fork(); // 調用fork()來創建一個新的子進程if (pid > 0){// 如果pid大于0,說明是父進程執行的代碼塊wait(&status); // 父進程等待子進程結束,并通過status變量獲取子進程的退出狀態printf("child quit, child status = %d\n", WEXITSTATUS(status)); // 打印子進程的退出狀態// 父進程在子進程結束后繼續執行while (1) {printf("cnt=%d\n", cnt); // 打印父進程中的計數器值printf("this is father print, pid = %d\n", getpid()); // 打印父進程的信息和PIDsleep(1); // 父進程休眠1秒,減緩循環速度}    }else if (pid == 0) {// 如果pid等于0,說明是子進程執行的代碼塊// 子進程進入一個無限循環while (1) {printf("this is child print, pid = %d\n", getpid()); // 打印子進程的信息和PIDsleep(1); // 子進程休眠1秒cnt++; // 子進程中的計數器增加if (cnt == 5) {exit(3); // 當計數器達到5時,子進程退出并返回狀態碼3}}    }return 0; // 程序理論上不會到達這里,因為父子進程都被設置在無限循環中
}

例子16? ?waitpid替代 wait檢查子狀態,waitpid允許父進程進行非阻塞檢查或等待特定的子進程結束

#include <stdio.h>    // 引入標準輸入輸出庫,用于打印
#include <sys/types.h> // 引入數據類型,包括 pid_t
#include <unistd.h>    // 引入 POSIX 操作系統API,包括 getpid(), fork() 和 sleep()
#include <stdlib.h>    // 引入標準庫,用于 exit()
#include <sys/wait.h>  // 引入等待函數庫,用于 waitpid()int main()
{pid_t pid; // 定義一個pid_t類型變量來存儲fork()的返回值int cnt = 0; // 定義并初始化計數器int status = 10; // 定義一個整數來存儲子進程的退出狀態pid = fork(); // 調用fork()來創建一個新的子進程if (pid > 0){// 如果pid大于0,說明是父進程執行的代碼塊waitpid(pid, &status, WNOHANG); // 使用非阻塞方式等待子進程結束,不會掛起父進程printf("child quit, child status = %d\n", WEXITSTATUS(status)); // 打印子進程的退出狀態// 父進程在子進程結束后繼續執行while (1) {printf("cnt=%d\n", cnt); // 打印父進程中的計數器值printf("this is father print, pid = %d\n", getpid()); // 打印父進程的信息和PIDsleep(1); // 父進程休眠1秒,減緩循環速度}    }else if (pid == 0) {// 如果pid等于0,說明是子進程執行的代碼塊// 子進程進入一個無限循環while (1) {printf("this is child print, pid = %d\n", getpid()); // 打印子進程的信息和PIDsleep(1); // 子進程休眠1秒cnt++; // 子進程中的計數器增加if (cnt == 5) {exit(3); // 當計數器達到5時,子進程退出并返回狀態碼3}}    }return 0; // 程序理論上不會到達這里,因為父子進程都被設置在無限循環中
}

例子17? ?子在一定條件下會自行退出,而父進程僅打印一次信息

#include <stdio.h>    // 引入標準輸入輸出庫,用于打印
#include <sys/types.h> // 引入數據類型,包括 pid_t
#include <unistd.h>    // 引入 POSIX 操作系統API,包括 getpid(), getppid(), fork() 和 sleep()
#include <stdlib.h>    // 引入標準庫,用于 exit()int main()
{pid_t pid; // 定義一個pid_t類型變量來存儲fork()的返回值int cnt = 0; // 定義并初始化計數器pid = fork(); // 調用fork()來創建一個新的子進程if (pid > 0){// 如果pid大于0,說明是父進程執行的代碼塊printf("this is father print, pid = %d\n", getpid()); // 打印父進程的信息和PID// 父進程沒有進入循環,將直接結束執行}else if (pid == 0) {// 如果pid等于0,說明是子進程執行的代碼塊// 子進程進入一個無限循環,直到cnt等于5while (1) {printf("this is child print, pid = %d, my father pid=%d\n", getpid(), getppid()); // 打印子進程的信息和其父進程的PIDsleep(1); // 子進程休眠1秒cnt++; // 子進程中的計數器增加if (cnt == 5) {exit(3); // 當計數器達到5時,子進程退出并返回狀態碼3}}    }return 0; // 父進程執行完打印后將結束,子進程在計數達到5后也將結束
}

例子18? ?execl執行一個新的程序。這個函數屬于 exec 系列函數,它們用于替換當前進程的映像

#include <stdio.h>    // 引入標準輸入輸出庫,用于打印
#include <stdlib.h>   // 引入標準庫,用于標準庫功能
#include <unistd.h>   // 引入 POSIX 操作系統API,包括 execl()// 函數原型:int execl(const char *path, const char *arg, ...);int main(void)
{// 打印 "before execl" 表明當前在調用 execl 前printf("before execl\n");// 調用 execl 執行名為 "echoarg" 的程序,該程序應在當前目錄下// "echoarg" 是被執行程序的名稱,同時也是傳遞給該程序的第一個參數// "abc" 是傳遞給 echoarg 程序的第二個參數// NULL 表示參數列表的結束if(execl("./echoarg", "echoarg", "abc", NULL) == -1){// 如果 execl 返回 -1,則表示執行失敗printf("execl failed!\n");// perror 用于打印上一個函數調用的錯誤描述(基于全局的 errno 變量)perror("why");}// 由于 execl 成功時不返回,如果程序執行到這里說明 execl 調用失敗printf("after execl\n");return 0;
}

例子19? ??execl函數來執行 /bin/ls 命令,通常用于列出目錄內容。如果 execl() 調用成功,則不會返回;如果調用失敗,會返回 -1 并打印錯誤信息

#include <stdio.h>    // 引入標準輸入輸出庫,用于打印
#include <stdlib.h>   // 引入標準庫,用于標準庫功能
#include <unistd.h>   // 引入 POSIX 操作系統API,包括 execl()// 函數原型:int execl(const char *path, const char *arg, ...);int main(void)
{// 打印 "before execl" 表明當前在調用 execl 前printf("before execl\n");// 調用 execl 執行位于 "/bin/ls" 的程序,通常用于列出目錄內容// "ls" 是傳遞給 /bin/ls 程序的參數,用于識別程序名稱// NULL 指示參數列表的結束if(execl("/bin/ls", "ls", NULL, NULL) == -1){// 如果 execl 返回 -1,則表示執行失敗printf("execl failed!\n");      // perror 用于打印上一個函數調用的錯誤描述(基于全局的 errno 變量)perror("why");}// 由于 execl 成功時不返回,如果程序執行到這里說明 execl 調用失敗printf("after execl\n");return 0;
}

例子20? ??execl函數來執行 /bin/ls 命令,配上 -l 選項來以長格式列出目錄內容。如果 execl() 調用成功,則會替換當前進程的映像并不返回;如果失敗,會返回 -1 并打印錯誤信息

#include <stdio.h>    // 引入標準輸入輸出庫,用于打印
#include <stdlib.h>   // 引入標準庫,用于標準庫功能
#include <unistd.h>   // 引入 POSIX 操作系統API,包括 execl()// 函數原型:int execl(const char *path, const char *arg, ...);int main(void)
{// 打印 "before execl" 表明當前在調用 execl 前printf("before execl\n");// 調用 execl 執行位于 "/bin/ls" 的程序,使用 "-l" 選項來以詳細列表格式列出文件和目錄// "ls" 是傳遞給 /bin/ls 程序的參數,用于識別程序名稱// "-l" 是一個參數,告訴 ls 命令以長格式顯示信息// NULL 指示參數列表的結束if(execl("/bin/ls", "ls", "-l", NULL) == -1){// 如果 execl 返回 -1,則表示執行失敗printf("execl failed!\n");      // perror 用于打印上一個函數調用的錯誤描述(基于全局的 errno 變量)perror("why");}// 由于 execl 成功時不返回,如果程序執行到這里說明 execl 調用失敗printf("after execl\n");return 0;
}

例子21? ??execl()執行系統命令 /bin/date,該命令用于顯示當前系統日期和時間。如果 execl()調用成功,它會替換當前進程的映像為 /bin/date 并不返回;如果失敗,會返回 -1 并打印錯誤信息

#include <stdio.h>    // 引入標準輸入輸出庫,用于打印
#include <stdlib.h>   // 引入標準庫,用于標準庫功能
#include <unistd.h>   // 引入 POSIX 操作系統API,包括 execl()// 函數原型:int execl(const char *path, const char *arg, ...);int main(void)
{// 打印信息,表明程序意圖獲取當前系統日期printf("this pro get system date:\n");// 調用 execl 執行位于 "/bin/date" 的系統命令// "date" 是傳遞給 /bin/date 程序的參數,用于識別程序名稱// NULL 指示參數列表的結束if(execl("/bin/date", "date", NULL, NULL) == -1){// 如果 execl 返回 -1,則表示執行失敗printf("execl failed!\n");      // perror 用于打印上一個函數調用的錯誤描述(基于全局的 errno 變量)perror("why");}// 由于 execl 成功時不返回,如果程序執行到這里說明 execl 調用失敗printf("after execl\n");return 0;
}

例子22? ??execlp()執行系統命令 ps,該命令用于顯示當前系統的進程狀態。如果 execlp() 調用成功,它會替換當前進程的映像為 ps 命令并不返回;如果失敗,會返回 -1 并打印錯誤信息

#include <stdio.h>    // 引入標準輸入輸出庫,用于打印
#include <stdlib.h>   // 引入標準庫,用于標準庫功能
#include <unistd.h>   // 引入 POSIX 操作系統API,包括 execlp()// 函數原型:int execl(const char *path, const char *arg, ...);int main(void)
{// 打印信息,表明程序意圖獲取當前系統進程狀態printf("this pro get system date:\n");// 調用 execlp 執行系統命令 "ps"// "ps" 是傳遞給 execlp() 的參數,用于執行 ps 命令顯示進程信息// NULL 指示參數列表的結束if(execlp("ps", "ps", NULL, NULL) == -1){// 如果 execlp 返回 -1,則表示執行失敗printf("execl failed!\n");// perror 用于打印上一個函數調用的錯誤描述(基于全局的 errno 變量)perror("why");}// 由于 execlp 成功時不返回,如果程序執行到這里說明 execlp 調用失敗printf("after execl\n");return 0;
}

例子23? ??execvp()執行系統命令 ps,用于顯示當前系統的進程狀態。execvp() 類似于 execlp(),但允許通過一個參數數組來傳遞命令和其參數。如果 execvp() 調用成功,它會替換當前進程的映像為 ps 命令并不返回;如果失敗,會返回 -1 并打印錯誤信息

#include <stdio.h>    // 引入標準輸入輸出庫,用于打印
#include <stdlib.h>   // 引入標準庫,用于標準庫功能
#include <unistd.h>   // 引入 POSIX 操作系統API,包括 execvp()// 函數原型:int execvp(const char *file, char *const argv[]);int main(void)
{// 打印信息,表明程序意圖獲取當前系統進程狀態printf("this pro get system date:\n");// 創建參數數組,用于傳遞給 execvp()char *argv[] = {"ps", NULL, NULL};// 調用 execvp 執行系統命令 "ps"// "ps" 是傳遞給 execvp() 的命令,argv 是命令和參數的數組if(execvp("ps", argv) == -1){// 如果 execvp 返回 -1,則表示執行失敗printf("execl failed!\n");      // perror 用于打印上一個函數調用的錯誤描述(基于全局的 errno 變量)perror("why");}// 由于 execvp 成功時不返回,如果程序執行到這里說明 execvp 調用失敗printf("after execl\n");return 0;
}

例子24? ??execv()執行 /bin/ps 命令,該命令用于顯示當前系統的進程狀態。execv() 類似于 execl(),但使用數組來傳遞命令和其參數。如果 execv() 調用成功,它會替換當前進程的映像為 /bin/ps 并不返回;如果失敗,會返回 -1 并打印錯誤信息

#include <stdio.h>    // 引入標準輸入輸出庫,用于打印
#include <stdlib.h>   // 引入標準庫,用于標準庫功能
#include <unistd.h>   // 引入 POSIX 操作系統API,包括 execv()// 函數原型:int execv(const char *path, char *const argv[]);int main(void)
{// 打印信息,表明程序意圖獲取當前系統進程狀態printf("this pro get system date:\n");// 創建參數數組,用于傳遞給 execv()char *argv[] = {"ps", NULL, NULL};  // "ps" 是命令名,NULL 表示參數列表結束// 調用 execv 執行位于 "/bin/ps" 的系統命令// "/bin/ps" 是命令的完整路徑// argv 是命令和參數的數組if(execv("/bin/ps", argv) == -1){// 如果 execv 返回 -1,則表示執行失敗printf("execl failed!\n");// perror 用于打印上一個函數調用的錯誤描述(基于全局的 errno 變量)perror("why");}// 由于 execv 成功時不返回,如果程序執行到這里說明 execv 調用失敗printf("after execl\n");return 0;
}

例子25? 輸入來觸發文件操作,在子進程中進行。這個例子特別是在輸入為 1 時,程序會修改配置文件 config.txt 中的一個特定值

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>int main()
{pid_t pid;  // 用于存儲進程IDint data = 10;  // 用戶輸入的數據初始化為10while(1) {  // 無限循環,直到程序被外部方式終止printf("please input a data\n");  // 提示用戶輸入數據scanf("%d", &data);  // 讀取用戶輸入的整數數據if(data == 1) {  // 如果輸入的數據為1,則進行文件操作int fdSrc;  // 文件描述符pid = fork();  // 創建子進程if(pid > 0) {wait(NULL);  // 父進程等待子進程完成}if(pid == 0) {  // 子進程代碼塊char *readBuf = NULL;  // 讀緩沖區指針fdSrc = open("config.txt", O_RDWR);  // 打開文件config.txt進行讀寫操作int size = lseek(fdSrc, 0, SEEK_END);  // 獲取文件大小lseek(fdSrc, 0, SEEK_SET);  // 將文件指針重置到文件開始readBuf = (char *)malloc(sizeof(char) * size + 8);  // 分配讀緩沖區內存int n_read = read(fdSrc, readBuf, size);  // 讀取文件內容到緩沖區char *p = strstr(readBuf, "LENG=");  // 在緩沖區中查找"LENG="if(p == NULL) {printf("not found\n");  // 如果沒有找到,打印未找到并退出exit(-1);}p = p + strlen("LENG=");  // 移動指針到"LENG="之后*p = '5';  // 修改內容lseek(fdSrc, 0, SEEK_SET);  // 將文件指針重置到文件開始int n_write = write(fdSrc, readBuf, strlen(readBuf));  // 將修改后的緩沖區內容寫回文件close(fdSrc);  // 關閉文件exit(0);  // 子進程退出}} else {printf("wait, do nothing\n");  // 如果輸入不是1,提示等待}}return 0;  // 主程序循環,實際上這里永遠不會執行到
}

例子26? ??根據輸入決定是否創建一個子進程來執行特定的程序 (changData),該程序預期對 config.txt 文件進行修改。如果輸入不是 1,則打印消息并繼續等待

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>int main()
{pid_t pid;  // 用于存儲進程IDint data = 10;  // 用戶輸入的數據初始化為10while(1) {  // 無限循環,直到程序被外部方式終止printf("please input a data\n");  // 提示用戶輸入數據scanf("%d", &data);  // 讀取用戶輸入的整數數據if(data == 1) {  // 如果輸入的數據為1,則進行操作int fdSrc;  // 文件描述符,雖然在此代碼版本中未被使用pid = fork();  // 創建子進程if(pid > 0) {wait(NULL);  // 父進程等待子進程完成}if(pid == 0) {  // 子進程代碼塊// 子進程執行一個外部程序 "changData"// 第一個參數 "./changData" 指定了程序的路徑// 第二個參數 "changData" 是傳遞給程序的 argv[0],即程序名// 第三個參數 "config.txt" 是傳遞給 changData 程序的參數,指定要操作的文件// NULL 表示參數列表的結束execl("./changData", "changData", "config.txt", NULL);// 如果execl執行失敗,則會繼續執行以下代碼perror("Failed to execute changData");  // 打印執行失敗的原因exit(1);  // 子進程失敗時退出}} else {printf("wait, do nothing\n");  // 如果輸入不是1,提示等待并什么也不做}}return 0;  // 主程序循環,實際上這里永遠不會執行到
}

例子27? ? 根據輸入決定執行一個外部命令(changData),該命令與配置文件 config.txt 相關聯。如果用戶輸入 1,程序會創建一個子進程,該子進程通過 system 函數調用外部程序 ./changData 來處理文件 config.txt

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>int main()
{pid_t pid;  // 用于存儲進程IDint data = 10;  // 用戶輸入的數據初始化為10while(1) {  // 無限循環,直到程序被外部方式終止printf("please input a data\n");  // 提示用戶輸入數據scanf("%d", &data);  // 讀取用戶輸入的整數數據if(data == 1) {  // 如果輸入的數據為1,則進行操作int fdSrc;  // 文件描述符,雖然在此代碼版本中未被使用pid = fork();  // 創建子進程if(pid > 0) {wait(NULL);  // 父進程等待子進程完成}if(pid == 0) {  // 子進程代碼塊// 子進程執行一個外部程序 "changData" 通過 system 函數// "./changData config.txt" 是被調用的命令,傳遞 'config.txt' 作為參數system("./changData config.txt");exit(0);  // 執行完外部命令后,子進程應正常退出}} else {printf("wait, do nothing\n");  // 如果輸入不是1,提示等待并什么也不做}}return 0;  // 主程序循環,實際上這里永遠不會執行到
}

例子28? ??system() 執行系統命令(在本例中是 ps),這個命令用來列出當前運行的進程。然而,該代碼示例存在一個問題:它沒有捕獲 system() 調用的輸出

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函數原型:int execl(const char *path, const char *arg, ...);int main(void)
{char ret[1024] = {0};  // 定義一個字符數組并初始化所有元素為0,用于存儲輸出system("ps");  // 調用system函數執行ps命令,ps命令用于顯示當前運行的進程// 注意:system函數實際上不會將命令輸出存儲在ret數組中printf("ret=%s\n", ret);  // 打印ret數組的內容,預期輸出為空字符串,因為system不會更改retreturn 0;
}

例子29? ?popen() 和 fread() 函數從 ps 命令獲取輸出并將其讀入到一個字符數組中。該程序展示了如何執行系統命令并捕獲其輸出,適合需要從命令行工具中直接讀取數據的場景

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
// 函數原型:int execl(const char *path, const char *arg, ...);
// size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)int main(void)
{char ret[1024] = {0};  // 創建字符數組,用于存儲命令輸出FILE *fp;  // 文件指針,用于執行 popen() 返回的流// 執行 'ps' 命令,并打開用于讀取的管道fp = popen("ps", "r");if (fp == NULL) {  // 檢查 popen 是否成功打開了管道perror("Failed to run command");  // 打印 popen 執行失敗的錯誤詳情exit(1);  // 退出程序}// 從 'ps' 命令的輸出流中讀取數據到 ret 數組中int nread = fread(ret, 1, 1024, fp);  // 讀取最多 1024 個字節到 ret// 打印讀取的字節數和內容printf("read ret %d byte, ret=%s\n", nread, ret);// 關閉管道pclose(fp);return 0;
}

例子30? ?處理命令行參數。它通過遍歷 argc 和 argv 數組來打印所有傳遞給程序的參數

#include <stdio.h>int main(int argc, char *argv[])  // main 函數接受命令行參數:argc 表示參數數量,argv 是參數字符串數組
{int i = 0;  // 定義循環計數變量for(i = 0; i < argc; i++)  // 循環遍歷所有命令行參數{printf("argv[%d]: %s\n", i, argv[i]);  // 打印每個參數的索引和內容}return 0;  // 程序正常結束
}

例子31? ?等待用戶輸入。當用戶輸入 1 時,程序會創建一個子進程,這個子進程會修改一個文件(./file1)中特定字符串("LENG=")之后的字符

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>int main()
{pid_t pid;  // 用于存儲進程IDint data = 10;  // 用戶輸入的數據初始化為10while(1) {  // 無限循環,直到程序被外部方式終止printf("please input a data\n");  // 提示用戶輸入數據scanf("%d", &data);  // 讀取用戶輸入的整數數據if(data == 1) {  // 如果輸入的數據為1,則進行操作pid = fork();  // 創建子進程if(pid > 0) {// 父進程執行的代碼塊// 父進程不做任何操作,繼續循環等待下一次輸入}else if(pid == 0) {// 子進程執行的代碼塊char *readBuf = NULL;  // 讀緩沖區指針int fdSrc;  // 文件描述符fdSrc = open("./file1", O_RDWR);  // 打開文件file1進行讀寫操作int size = lseek(fdSrc, 0, SEEK_END);  // 獲取文件大小lseek(fdSrc, 0, SEEK_SET);  // 將文件指針重置到文件開始readBuf = (char *)malloc(sizeof(char) * size + 8);  // 分配讀緩沖區內存int n_read = read(fdSrc, readBuf, size);  // 讀取文件內容到緩沖區char *p = strstr(readBuf, "LENG=");  // 在緩沖區中查找"LENG="if(p == NULL) {printf("not found\n");  // 如果沒有找到,打印未找到并退出exit(-1);}p += strlen("LENG=");  // 移動指針到"LENG="之后*p = '5';  // 修改內容lseek(fdSrc, 0, SEEK_SET);  // 將文件指針重置到文件開始int n_write = write(fdSrc, readBuf, strlen(readBuf));  // 將修改后的緩沖區內容寫回文件close(fdSrc);  // 關閉文件free(readBuf); // 釋放分配的內存exit(0);  // 子進程退出}}else {printf("wait, do nothing\n");  // 如果輸入不是1,提示等待并什么也不做}}return 0;  // 主程序循環,實際上這里永遠不會執行到
}

例子32? ??execl()函數是為了替換當前的進程映像為/bin/ls命令的進程映像

#include <stdio.h>   // 引入標準輸入輸出頭文件。
#include <stdlib.h>  // 引入標準庫頭文件,用于執行一些常規的函數操作,比如exit()。
#include <unistd.h>  // 引入UNIX標準函數定義頭文件,提供對POSIX操作系統API的訪問。// 函數原型聲明:int execl(const char *path, const char *arg, ...);
// execl()函數用于執行指定的文件路徑,將當前進程替換為一個新的進程。int main(void)
{printf("before execl\n");  // 在調用execl()前打印信息。// 調用execl()嘗試執行/bin/ls命令來列出目錄內容。"ls"是命令名,"-l"是參數。if(execl("/bin/ls", "ls", "-l", NULL) == -1){printf("execl failed!\n");  // 如果execl()返回-1,則說明執行失敗。perror("why");  // 使用perror()函數輸出錯誤原因。perror()會根據全局錯誤碼errno輸出錯誤描述。}// 如果execl()函數調用成功,則不會執行以下代碼,因為execl()會替換當前進程的映像,不會返回。printf("after execl\n");  // 如果execl()失敗,會繼續執行這里的代碼。return 0;  // 程序正常結束。
}

例子33? ?vfork()創建子進程并控制執行順序

#include <stdio.h>   // 引入標準輸入輸出頭文件,用于printf函數。
#include <sys/types.h>  // 引入數據類型定義,例如pid_t。
#include <unistd.h>  // 引入POSIX操作系統API,例如vfork和getpid函數。
#include <stdlib.h>  // 引入標準庫頭文件,用于執行一些常規的函數操作,如exit()。int main()
{pid_t pid;  // 聲明一個pid_t類型的變量來存儲進程ID。int cnt = 0;  // 計數器,用于子進程中記錄循環次數。pid = vfork();  // 創建一個子進程,子進程與父進程共享內存空間。if (pid > 0)  // 如果pid大于0,表示當前代碼塊在父進程中執行。{while (1) {  // 父進程無限循環。printf("cnt=%d\n", cnt);  // 打印當前計數器的值(注意:這個值在父進程中不會改變)。printf("this is father print, pid = %d\n", getpid());  // 打印父進程的ID。sleep(1);  // 暫停父進程1秒,以便觀察輸出。}   }else if (pid == 0) {  // 如果pid等于0,表示當前代碼塊在子進程中執行。while (1) {  // 子進程無限循環。printf("this is child print, pid = %d\n", getpid());  // 打印子進程的ID。sleep(1);  // 暫停子進程1秒,以便觀察輸出。cnt++;  // 子進程中計數器遞增。if (cnt == 3) {  // 如果計數器達到3,子進程退出。exit(0);  // 調用exit函數,正常終止子進程。}}   }return 0;  // 主程序結束(通常這個部分不會被執行到,因為父子進程已經進入了無限循環)。
}

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

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

相關文章

混合動力電動汽車介紹(二)

接續前一章內容&#xff0c;本篇文章介紹混合動力汽車串聯、并聯和混聯的系統組成和工作原理。 一、串聯混合動力電動汽車的系統組成和工作原理 上圖為串聯混合動力電動汽車的結構簡圖。汽車由電動機-發電機驅動行駛&#xff0c;電機控制器的動力來自油箱-發動機-發電機-發電機…

Python 爬蟲零基礎:探索網絡數據的神秘世界

Python 爬蟲零基礎&#xff1a;探索網絡數據的神秘世界 在數字化時代&#xff0c;網絡數據如同無盡的寶藏&#xff0c;等待著我們去發掘。Python爬蟲&#xff0c;作為獲取這些數據的重要工具&#xff0c;正逐漸走進越來越多人的視野。對于零基礎的學習者來說&#xff0c;如何入…

基于Spring Boot框架的分頁查詢和文件上傳

分頁查詢 分析 要想從數據庫中進行分頁查詢&#xff0c;我們要使用LIMIT關鍵字&#xff0c;格式為&#xff1a;limit 開始索引 每頁顯示的條數 假設一頁想展示10條數據 查詢第1頁數據的SQL語句是&#xff1a; select * from emp limit 0,10; 查詢第2頁數據的SQL語句是&…

【Pytest官方文檔翻譯及學習】2.2 如何在測試中編寫和報告斷言

目錄 2.2 如何在測試中編寫和報告斷言 2.2.1 使用assert語句斷言 2.2.2 關于預期異常的斷言 2.2.3 關于預期警告的斷言 2.2.4 應用上下文相關的比較 2.2.5 為失敗的斷言定義自己的解釋 2.2.6 斷言內省細節 2.2 如何在測試中編寫和報告斷言 2.2.1 使用assert語句斷言 p…

6、架構-服務端緩存

為系統引入緩存之前&#xff0c;第一件事情是確認系統是否真的需要緩 存。從開發角度來說&#xff0c;引入緩存會提 高系統復雜度&#xff0c;因為你要考慮緩存的失效、更新、一致性等問題&#xff1b;從運維角度來說&#xff0c;緩存會掩蓋一些缺 陷&#xff0c;讓問題在更久的…

npm徹底清理緩存

在使用npm過程中&#xff0c;肯定會遇到清緩存的情況&#xff0c;網上的命令一般為 npm cache clear --force有時筆者在清理緩存之后npm install依然失敗&#xff0c;仔細發現&#xff0c;執行該命令之后npm報了一個警告 npm WARN using --force Recommended protections dis…

代碼隨想錄算法訓練營第27天|● 39. 組合總和● 40.組合總和II● 131.分割回文串

組合總和 題目鏈接 39. 組合總和 - 力扣&#xff08;LeetCode&#xff09; 代碼&#xff1a; class Solution {public List<List<Integer>> res new ArrayList<>();public List<Integer> list new ArrayList<>();public int sum 0;/**…

在nginx中配置反向代理

在nginx中配置反向代理&#xff0c;需要使用proxy_pass指令。以下是一個簡單的nginx反向代理配置示例&#xff1a; server {listen 80;server_name example.com;location / {proxy_pass http://backend_server;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote…

LoadRunner 錄制腳本時提示無Internet訪問/加載慢,如何解決?

LoadRunner 錄制腳本時提示無Internet訪問/加載慢&#xff0c;如何解決&#xff1f; 在使用LoadRunner 12.02 進行錄制腳本時提示無Internet訪問&#xff0c;這是如下圖&#xff1a; 翻譯中文如下&#xff1a; 這里&#xff0c;我認為大家應該都已經點過yes了&#xff0c;但是…

python結構化模式匹配switch-case,Python 3.10中引入,Python的模式匹配(pattern matching)語法

增加了采用模式加上相應動作的 match 語句 和 case 語句 的形式的結構化模式匹配。 模式由序列、映射、基本數據類型以及類實例構成。 模式匹配使得程序能夠從復雜的數據類型中提取信息、根據數據結構實現分支&#xff0c;并基于不同的數據形式應用特定的動作。 語法與操作 模…

Linux下配置Pytorch

1.Anaconda 1.1虛擬環境創建 2.Nvidia驅動 3.CUDA驅動安裝 4.Pytorch安裝 具體的步驟如上&#xff1a;可參考另一位博主的博客非常詳細&#xff1a; Linux服務器配置PythonPyTorchCUDA深度學習環境_linux cuda環境配置-CSDN博客https://blog.csdn.net/NSJim/article/detai…

極海APM32F072用Keil5燒錄失敗Error: Flash Download failed -“Cortex-MO+“

在用Keil5燒錄時&#xff0c;出現錯誤彈窗&#xff0c;大概長這樣&#xff1a; 檢查了一圈設置&#xff0c;都搞不好。 先用J-Flash&#xff0c;顯示讀寫保護&#xff08;未截圖&#xff09;&#xff0c;會跳出界面讓選擇是否解除讀寫保護&#xff1a; 1.點擊允許讀操作YES&am…

DNF手游攻略:0氪攻略,轉職技巧與避坑指南!

在DNF手游的冒險旅程中&#xff0c;角色的轉職是一次重要的成長經歷。通過轉職&#xff0c;玩家可以獲得全新的技能和屬性&#xff0c;提升自己在地下城中的戰斗力。本文將為您介紹轉職后的關鍵技巧和日常任務&#xff0c;幫助您更好地適應新的職業身份&#xff0c;成為地下城中…

Python從0到100(二十九):requests模塊處理cookie

1 爬蟲中使用cookie 為了能夠通過爬蟲獲取到登錄后的頁面&#xff0c;或者是解決通過cookie的反扒&#xff0c;需要使用request來處理cookie相關的請求 1.1 爬蟲中使用cookie的利弊 帶上cookie的好處 能夠訪問登錄后的頁面能夠實現部分反反爬 帶上cookie的壞處 一套cookie往往…

數據庫與低代碼開發:技術革新與應用實踐

在數字化時代&#xff0c;企業對軟件開發的需求日益增長&#xff0c;同時對開發效率和成本控制的要求也越來越高。在這樣的背景下&#xff0c;低代碼開發平臺應運而生&#xff0c;它允許開發者通過圖形界面和配置化操作&#xff0c;快速構建應用程序&#xff0c;而無需編寫大量…

【設計模式】JAVA Design Patterns——Monitor(監視器模式)

&#x1f50d;目的 主要目的是為多個線程或進程提供一種結構化和受控的方式來安全地訪問和操作共享資源&#xff0c;例如變量、數據結構或代碼的關鍵部分&#xff0c;而不會導致沖突或競爭條件。 &#x1f50d;解釋 通俗描述 監視器模式用于強制對數據進行單線程訪問。 一次只允…

Windows線程同步的四種方式和區別

1. Windows線程同步的四種方式 2. 區別 Critical Section更多強調的是保護&#xff0c;Event對象、Mutex對象與Semaphore對象更多的強調的是同步&#xff1b;Critical Section對象是無法設置等待超時的&#xff0c;而其他三個對象則可以設置等待超時&#xff0c;從這一點來講…

ROS2在RVIZ2中加載機器人urdf模型

參考ROS2-rviz2顯示模型 我這邊用的solid works生成的urdf以及meshes&#xff0c;比參考的方法多了meshes 問題一&#xff1a;Error retrieving file [package://rm_dcr_description/meshes/leftarm_link7.STL]: Package [rm_dcr_description] does not exist 這個是urdf模型中…

VisualStudio中:如果某個項目不顯示SVN的show log等,而其他項目都正常

VisualStudio中&#xff1a;如果某個項目不顯示SVN的show log等&#xff0c;而其他項目都正常。說明大概率是當前項目的問題&#xff0c;而不是VisualStudio的問題&#xff01; 1.這個項目內有一個“隱藏”文件夾.svn 》先刪除&#xff01; 2.如果外層文件夾有紅色感嘆號&…

2024-5-14——完成所有任務需要的最少輪數

2024-5-14 題目來源我的題解方法一 哈希表數學 題目來源 力扣每日一題&#xff1b;題序&#xff1a;2244 我的題解 方法一 哈希表數學 根據數學規律可以發現&#xff0c;除了只有1個任務時不能完成任務&#xff0c;其他的都可以完成。并且需要的輪數為&#xff1a; ?x/3? …