tft每日頭條

 > 圖文

 > linux進程守護

linux進程守護

圖文 更新时间:2025-02-02 11:22:24

相關概念:

程序:編譯好的二進制文件,存放在磁盤上(占用的是物理内存空間),不占用系統資源(cpu,内存,打開的文件,設備,鎖)

進程:抽象的概念,與操作系統原理聯系緊密,是活躍的程序,占用系統資源,在内存中執行。

由原來的彈道程序涉及轉換成多道程序設計,是CPU分成若幹的時間碎片,各個進程搶占資源去執行,雖然程序有優先級高低,但是隻是搶占到的幾率高;即使是多核,也是需要時才開啟其他核。

處理速度:

寄存器--cache--内存--硬盤--網絡--存儲介質

其他概念:串行和并發,CPU和MMU

進程控制塊:PCB在usr/src/linux-headers/include/linux/sched.h文件中可以查看struct task_struct結構定義,包含部分定義,進程id,進程狀态,進程切換時需要保存和恢複的CPU寄存器,描述虛拟的地址空間信息,當前工作目錄,文件描述符表,用戶id和組id,繪畫和進程組,資源上限,umask掩碼

進程狀态

初始态(創建時,非常短暫),就緒态(有執行資格,但是沒有執行權限,需要搶占資源),,運行态(正在執行),挂起态(沒有執行資格和執行權限),終止态

linux進程守護(linux進程控制)1

進程控制

程序默認的是單進程的; 下面介紹多進程的使用

創建進程函數: pid_t fork(void);(查看 Linux下使用命令:man 2 fork)

linux進程守護(linux進程控制)2

返回值: 失敗返回-1, 父進程返回子進程ID, 子進程返回0

查看當前進程 ps aux | grep "要查找的程序"; ps ajx

linux進程守護(linux進程控制)3

剛fork完成時(父子進程之間) 1. 0-3G地址空間相同 2. PCB相同, 但是pid除外 3.其他内容由mmu映射到物理内存上, 讀時共享, 寫時複制獲取pid 和 ppid 對應的函數是getpid(); getppid();

//wait 函數回收子進程 #include <stdlib.h> #include <stdio.h> #include <unistd.h> int main() { pid_t pid; pid = fork(); if(pid == -1) { perror("fork error"); exit(-1); } else if(pid > 0) { printf("parent process\n"); } else if(pid == 0) { printf("child process\n"); } printf("mul process\n"); return 0; }

回收進程

進程有孤兒進程, 僵屍進程

  1. 孤兒進程 : 子進程活着, 父進程死了, linxu中的init進程會領養孤兒
  2. 僵屍進程 : 子進程死了, 父進程正在忙, 沒有去回收子進程
  3. 進程回收 : 代碼附在下邊

wait - 阻塞函數

pid_t wait(int* status);

調用一次回收一個子進程資源

返回值:

0: 回收的子進程的pid;

-1: 沒有子進程可以回收了;

status -- 傳出參數

獲取退出時候的返回值

waitpid -- pid_t waitpid(pid_t pid, int *status, int options);

(可以設置非阻塞, 提高wait的效率)

pid: -1: 所有的子進程

0: 當前進程組的子進程

0(pid): 回收指定進程的pcb

-pid: 回收不在當前進程組的子進程

opttions: 阻塞: 0

非阻塞: WNOHANG 可以設置為非阻塞

可以有針對性的回收某一個子進程資源 ;需要注意的是即使是非阻塞, 也需要循環來回收子進程

//wait函數回收子進程 #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <string.h> #include <sys/wait.h> int counter = 100; int main(int argc, const char* argv[]) { int number = 5; int i; pid_t pid; for(i=0; i<number; i) { pid = fork(); if(pid == 0) break; } if(i<number) { // 子進程 counter = 100; printf("child pid = %d, ppid = %d\n", getpid(), getppid()); printf("counter = %d\n\n", counter); //sleep(100); exit(9); } else if(i == number) { counter = 300; printf("parent pid = %d, ppid = %d\n", getpid(), getppid()); printf("counter = %d\n\n", counter); sleep(1); // 回收子進程 int status; pid_t wpid; while( (wpid=wait(&status)) != -1) { // 正常退出 if(WIFEXITED(status)) { printf("porcess exit by number: %d\n", WEXITSTATUS(status)); } // 被信号殺死 else if(WIFSIGNALED(status)) { printf("process kill by signal: %d\n", WTERMSIG(status)); } printf("child died pid = %d\n", wpid); } } return 10; }

//驗證父子進程是否文件共享 #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <string.h> #include <fcntl.h> int main(int argc, const char* argv[]) { int fd = open("temp", O_CREAT | O_RDWR, 0664); if(fd == -1) { perror("open error"); exit(1); } pid_t pid = fork(); if(pid == -1) { perror("fork error"); exit(1); } if(pid > 0) { char* p = "123123123"; write(fd, p, strlen(p) 1); } else if(pid == 0) { // 睡1s保證父進程已經完成了文件的寫操作 sleep(1); char buf[1024]; lseek(fd, 0, SEEK_SET); int len = read(fd, buf, sizeof(buf)); printf("%s\n", buf); } close(fd); return 0; }

//子進程執行不同任務, 父進程負責回收子進程 #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <string.h> int main(int argc, const char* argv[]) { int i = 0; int number = 3; pid_t pid; for(i = 0; i<number; i) { pid = fork(); if(pid == 0) { break; } } // 父進程 if(i == number) { sleep(2); // 回收子進程 pid_t wpid; int status; while( (wpid = waitpid(0, &status, WNOHANG)) != -1 ) { if(wpid == 0) { continue; } printf("child pid = %d\n", wpid); if(WIFEXITED(status)) { printf("return number: %d\n", WEXITSTATUS(status)); } else if(WIFSIGNALED(status)) { printf("exit by signal: %d\n", WTERMSIG(status)); } } } else if(i == 0) { execl("/home/kevin/test/app", "app", NULL); } else if(i == 1) { execl("./error", "error", NULL); } else if(i == 2) { execlp("ps", "ps", "aux", NULL); } printf("over......\n"); return 0; }

//waitpid 來回收子進程, 注意非阻塞時也需要循環去回收 #include <stdio.h> #include <sys/wait.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <string.h> int main(int argc, const char* argv[]) { int num = 3; int i = 0; pid_t pid; for(i=0; i<num; i) { pid = fork(); if(pid == 0) { break; } } if(i == 0) { execlp("ps", "ps", "aux", NULL); perror("execlp ps"); exit(1); } else if(i == 1) { execl("/home/kevin/test/app", "app", NULL); perror("execl app"); exit(1); } else if(i == 2) { execl("./error", "error", NULL); perror("execl error"); exit(1); } else if(i == num) { // 回收 int status; pid_t wpid; while( (wpid = waitpid(-1, &status, WNOHANG)) != -1 ) { if(wpid == 0) continue; printf(" ----- child died pid = %d\n", wpid); if(WIFEXITED(status)) { printf("return value %d\n", WEXITSTATUS(status)); } else if(WIFSIGNALED(status)) { printf("died by signal: %d\n", WTERMSIG(status)); } } } return 0; }

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关圖文资讯推荐

热门圖文资讯推荐

网友关注

Copyright 2023-2025 - www.tftnews.com All Rights Reserved