進程id:系統中每一個進程有惟一的id,在c語言中用pid_t類型表示,是個非負整數。linux
進程狀態:就緒,運行,掛起,中止等狀態c++
描述虛擬地址空間的信息shell
描述控制終端的信息bash
進程執行時的當前工做目錄(current working directory)微信
umask掩碼session
文件描述符表,包含不少指向file結構體的指針函數
和信號相關的信息學習
用戶id和組id編碼
會話(session)和進程組spa
進程可使用的資源上限(Resource Limit)
用【ulimit -a】查看:
ys@ys:~$ ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 7743 max locked memory (kbytes, -l) 16384 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 7743 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
查看全部的環境變量:env
環境寫法:等號先後沒有空格
KEY=VALUE
經常使用的環境變量:
獲取環境變量:getenv
#include <stdlib.h> char *getenv(const char *name);
返回值:
成功:返回指針
失敗:返回NULL
設置環境變量:setenv
#include <stdlib.h> int setenv(const char *name, const char *value, int overwrite);
刪除環境變量:unsetenv
#include <stdlib.h> int unsetenv(const char *name);
設置環境變量和刪除環境變量通常不用系統函數,而是編輯【~/.bashrc】文件。
使用【exprot key=value】。
建立進程:fork
#include <sys/types.h> #include <unistd.h> pid_t fork(void);
得到當前進程本身id:getpid
得到當前進程的父進程的id:getppid
ss #include <unistd.h> pid_t getpid(void); pid_t getppid(void);
理解fork的小例子:
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> int main(){ //char* val = getenv("HOME"); printf("begin...\n"); pid_t pid = fork(); printf("end...\n"); }
執行結果:
ys@ys:~/test$ ./en begin... end... ys@ys:~/test$ end...
從執行結果發下:
1,【begin】被打印出1次;【end】被打印出2次。
2,第二個【end】跑到了shell的後面。
分析:
下面的例子能夠了解,getpid和getppid的用法:
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> int main(){ //char* val = getenv("HOME"); printf("begin...\n"); pid_t pid = fork(); //child process if(pid == 0){ printf("child: pid=%d, ppid=%d\n", getpid(), getppid()); } //parent proces else if(pid > 0){ printf("parent: pid=%d, child id:%d\n", getpid(), pid); sleep(1);//爲了讓子進程先結束 } printf("end...\n"); }
查看進程的命名:ps
ys@ys:~$ ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.3 159928 7536 ? Ss 13:53 0:02 /sbin/init spla root 2 0.0 0.0 0 0 ? S 13:53 0:00 [kthreadd] ys 4029 0.0 0.0 4508 812 pts/0 S+ 16:30 0:00 ./en ys 4030 0.0 0.0 4508 80 pts/0 S+ 16:30 0:00 ./en ys 4043 0.1 0.2 29560 4936 pts/1 Ss 16:30 0:00 bash ys 4051 0.0 0.1 44472 3700 pts/1 R+ 16:30 0:00 ps aux
從下圖能夠看出子進程4030的父進程是4029,父進程4029的父進程是1671,進程1671是bash(shell)程序。因此的進程都是從進程1:【/sbin/init splash】衍生出來的。
ys@ys:~$ ps ajx PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 0 1 1 1 ? -1 Ss 0 0:02 /sbin/init splash 1661 1671 1671 1671 pts/0 4029 Ss 1000 0:00 bash 1671 4029 4029 1671 pts/0 4029 S+ 1000 0:00 ./en 4029 4030 4029 1671 pts/0 4029 S+ 1000 0:00 ./en 1661 4043 4043 4043 pts/1 4055 Ss 1000 0:00 bash 4043 4055 4055 4043 pts/1 4055 R+ 1000 0:00 ps ajx
給進程發送信號:kill
使用【kill -l】查看信號列表,發現9號信號就殺死進程的信號。
ys@ys:~$ kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX
由父進程建立5個子進程的例子:
#include <sys/types.h> #include <unistd.h> #include <stdio.h> int main(){ int i = 0; pid_t pid = 0; for(i = 0; i < 5; ++i){ pid = fork(); if(pid == 0){ //child process //printf("child: pid=%d, ppid=%d\n", getpid(), getppid()); break; } else if (pid > 0){ //parent process //printf("parent: pid=%d, ppid=%d\n", getpid(), getppid()); } } sleep(i); printf("proces:%d will die:pid=%d,ppid=%d\n", i,getpid(), getppid()); }
執行結果:
ys@ys:~/test$ ./fo proces:0 will die:pid=2139,ppid=2138 proces:1 will die:pid=2140,ppid=2138 proces:2 will die:pid=2141,ppid=2138 proces:3 will die:pid=2142,ppid=2138 proces:4 will die:pid=2143,ppid=2138 proces:5 will die:pid=2138,ppid=1704
要點在【break】和【sleep(i)】這2個地方。
不加break的話,子進程也會建立子進程。
觀察【sleep(i);]這行,執行到這行的時間點,若是i=0,則說明是第一建立的子進程;
若是i=4,說明是最後建立的子進程,若是i=5,說明是父進程。因此根據i的值,進行sleep,就可以實現先建立的子進程先執行完,後建立的後執行完,最後纔是父進程執行完。
在當進程調用別的程序:execl和execlp
#include <unistd.h> int execl(const char *path, const char *arg, .../* (char *) NULL */); int execlp(const char *file, const char *arg, .../* (char *) NULL */);
調用ls的例子:
#include <unistd.h> #include <stdio.h> int main(){ execl("/bin/ls", "ls", "-l", "--color=auto", NULL); perror("ls"); printf("not back\n"); }
孤兒進程和殭屍進程
孤兒進程:父進死了,被init進程領養,變成孤兒進程。
殭屍進程:子進程死了,但父進程沒有回收子進程的資源(pcb(大結構體)),變成殭屍進程。
回收殭屍進程的方法:不能再用kill去殺,殺死父進程,讓init領養,init負責回收。
查看殭屍進程:
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 1704 2683 2683 1704 pts/0 2683 S+ 1000 0:00 ./zo 2683 2684 2683 1704 pts/0 2683 Z+ 1000 0:00 [zo] <defunct>
發現有【Z+】和《defunct》就是殭屍進程。
回收子進程:wait函數
#include <sys/types.h> #include <sys/wait.h> pid_t wait(int *wstatus);
做用:
wstatus:傳出參數,裏面有子進程死亡的緣由。
查看wstatus的方法:使用下面2組宏。
WIFEXITED(wstatus) WEXITSTATUS(wstatus) WIFSIGNALED(wstatus) WTERMSIG(wstatus)
正常死亡:WIFEXITED(wstatus)返回真,使用WEXITSTATUS(wstatus)獲得退出狀態。
退出狀態的具體含義:return 後面的數字;或者exit 括號裏的數字。
非正常死亡(被信號殺死):WIFSIGNALED(wstatus)返回真,使用WTERMSIG(wstatus)獲得殺死它的信號(kill -l 顯示出來的數字)。
返回值:
wait的例子:
#include <sys/types.h> #include <unistd.h> #include <stdio.h> #include <wait.h> #include <stdlib.h> int main(){ int i = 0; pid_t pid = 0; pid = fork(); if(pid == 0){ //child process while(1){ printf("child: pid=%d, ppid=%d\n", getpid(), getppid()); sleep(3); //return 101; //exit(111); //sleep(2); } } else if (pid > 0){ //parent process printf("parent: pid=%d, ppid=%d\n", getpid(), getppid()); int wstatus; pid_t pid = wait(&wstatus); if(WIFEXITED(wstatus)){ printf("child die pid=%d, status=%d\n",pid, WEXITSTATUS(wstatus)); } if(WIFSIGNALED(wstatus)){ printf("child die pid=%d, status=%d\n",pid, WTERMSIG(wstatus)); } } }
分析:
回收子進程:waitpid
#include <sys/types.h> #include <sys/wait.h> pid_t waitpid(pid_t pid, int *wstatus, int options);
<font color="green">
</font>