1. 程式人生 > >二十六、Linux 進程與信號---system 函數 和進程狀態切換

二十六、Linux 進程與信號---system 函數 和進程狀態切換

idt erro lib IV lin sig 進入 空指針 權限

26.1 system 函數

26.1.1 函數說明

system(執行shell 命令)
相關函數 fork,execve,waitpid,popen

1 #include <stdlib.h>
2 int system(const char * string);
  • 函數功能:簡化 exec 函數
  • 函數說明
    • system()會調用 fork() 產生子進程,由子進程來調用 /bin/sh -c string 來執行參數 string 字符串所代表的命令,此命令執行完後隨即返回原調用的進程。
    • 在調用 system() 期間 SIGCHLD 信號會被暫時擱置,SIGINT 和 SIGQUIT 信號則會被忽略。
    • 等同於 /bin/bash -c "cmd" 或者 exec("bash", "-c", "cmd")
  • 返回值
    • 如果 system()在調用 /bin/sh 時失敗則返回 127,其他失敗原因返回-1。
    • 若參數 string 為空指針(NULL),則返回非零值。
    • 如果system()調用成功則最後會返回執行 shell 命令後的返回值,但是此返回值也有可能為 system()調用 /bin/sh 失敗所返回的 127,因此最好能再檢查 errno 來確認執行成功。
  • 附加說明
    • 在編寫具有SUID/SGID權限的程序時請勿使用 system(),system() 會繼承環境變量,通過環境變量可能會造成系統安全的問題。

26.1.2 system 應用

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <unistd.h>
 4 
 5 char *cmd = "date";
 6 
 7 int main(void)
 8 {
 9     system("clear");
10     system(cmd);
11 
12     return 0;
13 }

  編譯執行

  技術分享圖片

26.1.3 構建 mysystem 命令

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3
#include <unistd.h> 4 #include <sys/types.h> 5 #include <sys/wait.h> 6 7 char *cmd1 = "date > s1.txt"; 8 char *cmd2 = "date > s2.txt"; 9 10 void mysystem(char *cmd) 11 { 12 pid_t pid; 13 if((pid = fork()) < 0) { 14 perror("fork error"); 15 exit(1); 16 } else if(pid == 0) { 17 if(execlp("/bin/bash", "/bin/bash", "-c", cmd ,NULL) < 0) { 18 perror("execlp error"); 19 exit(1); 20 } 21 } 22 23 wait(0); 24 } 25 26 int main(void) 27 { 28 system("clear"); 29 system(cmd1); 30 31 mysystem(cmd2); 32 33 return 0; 34 }

  編譯調試

  技術分享圖片

26.6 進程狀態切換

  技術分享圖片

  • runnable:就緒狀態
  • running:運行狀態
  • block/suspend:阻塞或掛起狀態
  • dead:終止狀態。正在運行的狀態調用 return/exit_exit 進入 dead 狀態
  • os scheduler:系統調度

二十六、Linux 進程與信號---system 函數 和進程狀態切換