进程常用指令 (从创建到回收 包含守护)
??????????????????????????????????????????????????????????????????????????????? 進程
?
????????????????????????? 常用命令及基本介紹
?
ps -ef 查看所有進程信息 (一般需要配合管道使用)
ps aux 查看進程信息 且顯示進程狀態
狀態:
R 運行態 正在運行或可運行
D 等待態 不可中斷
S 等待態 可中斷
T 停止態
Z 僵尸態
可追加:
+ 前臺運行
< 高優先級進程
N 低優先級進程
top 動態的查看進程的信息及狀態 每隔3秒刷新一下 且能根據CPU的占用情況從大到小排序
?
/proc 目錄中存放著一些進程相關文件
status 文件中存放進程信息
fd 目錄中 存放進程打開的所有文件的信息
?
nice -n number +./執行文件名 作用是修改進程的優先級 (number 為設定優先級的大小 范圍為-20 ~ 19 19最低)
?
renice -n number +進程號 作用是一般用于修改已有進程的優先級 (number的作用同上)
?
普通用戶只能降低優先級 不能拉高優先級
ROOT用戶 可以降低優先級也可以拉高優先級
jobs 顯示當前所有后臺進程及信息 并對其編號排序
?
fg +排序號(jobs的排序號) 把相應的后臺進程轉成前臺進程
?
Ctrl +z 讓前臺運行進程轉成掛起進程(停止態)
bg +排序號 讓掛起進程轉成后臺運行進程
?
??????????????????????????????????????????????? 創建進程
?
?
創建進程函數
#include<unistd.h>
pid_t fork(void);
失敗返回-1
如果成功 父進程返回子進程的進程號 子進程返回0
?
int getpid(void) 返回進程號
?
子進程繼承了父進程幾乎所有內容 但不是全部
父子進程都有自己獨立的空間
?
若父進程先結束
子進程成為孤兒進程 被init進程收養 (也就是說它的父進程變為init進程)
子進程變成后臺進程
?
若子進程先結束
父進程如果沒有及時回收 子進程會變成僵尸進程
?
子進程是在fork()函數之后的下一條語句開始執行
子進程被創建后 父子進程誰先執行? 系統先調用誰 誰就先執行 (如果沒有發生進程調度 則父子進程都有可能先執行)
父進程能否多次調用fork()函數? 可以 理論上不受影響
子進程能否多次調用fork()函數? 可以 理論上不受影響
?
結束進程
#include<stdlib.h>
#include<unistd.h>
void exit(int status)
void _exit(int status)
都會結束當前進程 并返回status
exit()結束進程時 會刷新緩沖區(流)
?
?
????????????????????????????????????????????????? exec函數族
?
進程調用exec函數族執行某個程序
進程當前程序被執行程序替換
讓父子進程執行不同的程序
父進程創建子進程
子進程調用exec函數族·
父進程不受影響
?
#include<unistd.h>
int execl(const char *path, const char *arg, ...)
int execlp(const char *file, const char *arg,...)
?
成功則執行指定程序 失敗則返回EOF
path 執行的程序的名稱 包含路徑
arg.... 傳遞給程序的參數
file 執行的程序的名稱 不含路徑 需要在PATH環境變量中查找
?
#include<unistd.h>
int execv(const char *path, char *const argv[],...)
int execvp(const char *file, char *const srgv[],....)
成功執行指定程序 失敗返回EOF
arg....封裝成指針數組的形式
?
Ps:char *arg[]= {"ls","-a", "-l", "/etc", NULL};
if(execv("/bin/ls", arg) < 0)
{
perror("execv");
}
?
#include <stdlib.h>
int system(const char *command)
成功返回command命令的返回值 失敗返回EOF
函數的實現過程 是 先創建一個子進程 然后system()在子進程中執行命令 父進程需要等待子進程執行完之后才能繼續執行
?
???????????????????????????????????? 進程回收
?
子進程結束時 由父進程回收
孤兒進程 由init進程回收
如果沒有及時回收 那么就會變成僵尸進程 直到其父進程執行結束 僵尸進程才會被init進程回收
?
進程回收函數
#include<unistd.h>
pid_t wait(int *status)
成功返回被回收的子進程的進程號 失敗返回EOF
如果子進程沒有結束 父進程會一直處于阻塞狀態
若有多個子進程 哪個先結束 哪個先被回收
status用于保存子進程返回值和結束方式的地址
status 如果為NULL 表示直接釋放子進程的pcb 不接收返回值
?
子進程正常結束的三種方式 exit / _exit / return 這三種都會返回一個值(0-255)
父進程調用wait(status)進行回收
WIFEEXITED(status) 可通過這個宏定義判斷這個子進程是否是正常結束
WEXITSTATUS(status) 獲取子進程返回值
WIFSIGNALED(status) 判斷子進程是否是被信號結束
WTERMSIG(status) 獲取結束子進程的信號類型
?
status這個變量中 第0位到第6位存放子進程結束類型 如果為0 說明正常結束 非零說明被信號結束
第8位到第15位存放子進程結束的返回值
?
?進程回收函數
#include <unistd.h>
pid_t waitpid(pid_t pid, int *status, int option)
參數pid 是指定回收的對象 (如果不想指定 值設為-1即可)
參數option 是指定回收的方式 0或WNOHANG
option為0 如果子進程尚未結束 父進程則一直處于阻塞狀態 等待其結束 并將其回收
option為WNOHANG 如果子進程尚未結束 父進程不會一直阻塞 waitpid會返回0 代表子程序沒結束
如果子程序結束了 waitpid會返回進程號 代表回收成功
成功則返回子進程的進程號或0 失敗返回EOF
如果返回進程號 說明回收成功
如果返回0 說明子進程還沒結束 并不代表回收失敗
如果返回EOF 說明沒有子進程
?
??????????????????????????????????????????????? 守護進程
?
守護進程通常在系統啟動時運行 系統關閉時 結束
在linux系統中大量使用 很多服務程序以守護進程形式運行
?
特點:
始終在后臺運行
獨立于任何終端
周期性的執行某種任務或等待處理特定事件
?
linux以會話和進程組的方式管理進程
每一個進程都屬于一個進程組
會話是一個或多個進程組的集合 通常用戶打開一個終端時 系統會創建一個會話 所有通過該終端運行的進程都屬于這個會話
一個會話最多只能打開一個終端(也可以不打開)
當某個終端結束時 所有相關的進程都會被結束
?
?
????????? 守護進程的創建
?
1. 創建子進程 父進程退出
此時該子進程會成為孤兒進程被init進程收養 且在后臺運行
并且該子進程依然依附于終端 一旦終端關閉子進程會被結束
(此時進程還不屬于守護進程)
?
2. 在子進程中 創建新會話
實現函數 setsid()
該子進程成為會話組組長
且不再依賴于原先終端
?
3. 更改當前工作目錄
可更改為
chdir("/")(這是根目錄 普通用戶的權限是只讀 可執行 不可寫)
或 chdir("/tmp")(所有的用戶在該目錄下都是可讀可寫可執行)
更改目錄的原因:守護進程一直在后臺運行 其工作目錄是不可被卸載的 所以創建守護進程時 需 要把子進程的工作目錄更改到一個永遠不會被修改的目錄中
?
4.重設文件權限掩碼
實現函數 umask(number) number為設定的掩碼 一般為0 代表不會屏蔽任何權限位
重新設定的掩碼只會對當前進程有效 不會影響其他進程
5 關閉打開的文件描述符
因為子進程會繼承父進程的一些文件 所以在這里需要把這些文件關閉掉
實現函數 getdtablesize() 作用獲取文件個數
int i;
for(i=0; i<getdablesize();i++)
close(i);
已脫離終端 stdin /stdout / stderr 無法使用
?
Like:
創建守護進程 每隔1秒 將系統時間寫入到time.log文件中
?
code:
int main()
{
pid_t pid;
FILE *fp;
time_t t;
int i;
?
if((pid = fork() < 0)
{
perror("fork");
exit(-1);
}
else if(pid > 0)
exit(0);
?
setpid();//創建新會話
umask(0); //重設文件掩碼
chdir("/tmp"); // 更改文件目錄
?
for(i =0 ;i < getdablesize(); i++) //關閉繼承的父進程的文件
close(i);
?
if((fp = fopen("time.log", "a")) == NULL)
{
perror("fopen");
exit(-1);
}
?
while(1)
{
time(&t);
fprintf(fp, "%s", ctime(&t));
fflush(fp);
sleep(1);
}
}
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
總結
以上是生活随笔為你收集整理的进程常用指令 (从创建到回收 包含守护)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux中标准I/O 文件I/O 及库
- 下一篇: 光遇风行季小金人怎么收集