<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                > Linux 進程是正在執行中的程序 [TOC] ## 1 進程簡介 啟動進程有兩種方式: - 手工啟動 - 前臺啟動:執行一條命令 - 后臺啟動:在命令后輸入一個`&`符號 - 調度啟動 - 例如定時執行,輸入 `at 11:27 12/25/2020`,輸入命令`ls -l`,再輸入`Ctrl + D`退出;或者使用相對時間,輸入`at now +5 min`;結果不會在終端回顯,可以重定向到文件中查看 > Linux 常見進程操作命令 命令 | 作用 ---- | ---- ps | 查看系統中的進程 top | 動態顯示系統中的進程 nice | 按用戶執行的優先級運行 renice | 改變正在運行的進程的優先級 kill | 終止進程(包括后臺進程) crontab | 用于安裝、刪除或者列出用于驅動 cron 后臺進程的任務 bg | 將掛起的進程放到后臺執行 fg | 把后臺進程轉到前臺執行 ## 2 進程控制 系統會為每個新創建的進程分配一個唯一的正整數,稱為進程標識符(PID),父進程的為(PPID),可以通過 `getpid` 和 `getppid` 獲取 > Linux C 與進程相關的主要函數 函數名稱 | 功能 ---- | ---- getpid | 獲取當前進程的進程號 getppid | 獲取當前進程的父進程號 exec 函數族 | 在進程中啟動另一個進程執行 system | 在進程中開始另一個進程 fork | 從已存在的進程中復制一個新進程 sleep | 令當前進程進入睡眠狀態,直到達到指定時間,或者被信號中斷 exit | 正常終止進程,并把參數 status 返回給父進程,進程中的所有緩沖區數據會自動寫回并關閉未關閉的文件 _exit | 立即終止進程,并把參數 status 返回給父進程 ,并關閉未關閉的文件,不會處理標準I/O緩沖區 wait | 暫停父進程,等待子進程運行完成 waitpid | 暫停父進程,等待子進程運行完成 ### 2.1 進程創建 **1. fork函數** > fork 函數示例(備注:vfork 函數可以保證子進程一定優先于父進程開始執行) ```c #include <sys/types.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> int main(void) { pid_t pid; char *message; int n; pid = fork(); if (pid < 0) { // 進程創建失敗 perror("fork failed"); exit(1); } else if (pid == 0) { // 子進程執行 message = "子進程執行"; n = 3; } else { // 父進程執行 message = "父進程執行"; n = 6; } for (; n > 0; n--) { printf(message); // 父進程與子進程交替打印 sleep(1); } return 0; } ``` **2. exec 函數族** ```c execl --- [把可變參數保存到以NULL結尾的指針函數中] ---> execv execle --- [把可變參數保存到以NULL結尾的指針函數中] ---> execve execlp --- [把可變參數保存到以NULL結尾的指針數組中] ---> execvp ---[依次在PATH環境變量指示的各目錄中查找該程序] ---> execv --- [使用enviorn所指向的當前環境變量表] --> execve 系統調用 exec 函數族的六個成員函數的語法(頭文件`#include <unistd.h>`),省略了`exec`前綴 int l (const char *path, const char *arg, ...) // 列表傳遞 int v (const char *path, char const *argv[]) // 字符串傳遞 int le (const char *path, const char *arg, ..., char *const envp[]) int ve (const char *path, char *const argv[], char *const envp[]) int lp (const char *file, const char *arg, ...) int vp (const char *file, char *const argv[]) ``` ### 2.2 進程終止 有五種方式使進程終止: - 正常終止 - 在 main 函數內執行 return 語句,等效于調用 exit - 調用 exit 函數(由ANSI C定義),其操作包括調用各終止處理程序,然后關閉所有標準I/O流等 - 異常終止 - 調用 abort - 由一個信號終止 ### 2.3 僵尸進程 一個已經終止運行、但其父進程尚未對其**善后處理**(獲取終止子進程的有關信息、釋放它仍然占用的資源)的進程被稱為僵尸進程(zombie),ps 將僵尸進程的狀態顯示為`Z` 可以在父進程中調用 `wait` 或 `waitpid` 函數,使子進程比父進程早終止,而讓父進程有機會了解子進程終止時的狀態 - wait 用于使父進程阻塞,直到一個子進程終止或者該進程接到了一個指定的信號為止 - waitpid 有若干選項,也能支持作業控制,wait 只是 waitpid 的一個特例 **init** 進程是Linux啟動后創建的第一個進程,當一個程序退出,它的子進程會被 init 進程繼承 ### 2.4 守護進程 守護進程最重要的特性是**后臺運行**,其次守護進程必須與其運行前的環境隔離開來(包括未關閉的文件描述符、控制終端、會話和進程組、工作目錄以及文件創建掩碼),可以通過 `/etc/rc.d`、`crond 進程`或用戶終端啟動 輸入 `ps -aux`后: - init 系統守護進程,PID 為 1,負責啟動各層次特定的系統服務,這些服務通常是由它們自身的守護進程實現的 - keventd 守護進程,為在內核中運行計劃執行的函數提供進程上下文 - kswapd 守護進程,頁面置換守護進程 - bdflush 和 kupdated 守護進程,Linux內核使用 - portmap 端口映射守護進程,提供將RPC程序號映射為網絡端口號的服務 - syslogd 守護進程,可幫助操作人員把系統消息記入日志 - inetd 守護進程(xinetd),監聽系統網絡接口,以便取得來自網絡的對各種網絡服務進程的請求 - nfsd,lockd,rpciod 守護進程,提供對網絡文件系統(NFS)的支持 - cupsd 守護進程,打印脫機進程,處理對系統提出的所有打印請求 編寫守護進程的要點: 1. 創建子進程,終止父進程 2. 在子進程中創建新會話(例如setsid) 3. 改變工作目錄(chdir) 4. 重設文件掩碼(unmask(0)) 5. 關閉文件描述符(遍歷NOFILE,close(i)) ```c void init_daemon(void); int main() { FILE *fp; time_t t; init_daemon(); while (1) { sleep(10); if (fp=fopen("xxx.log") >= 0) { t = time(0); fprintf(fp, "%s", asctime(localtime(&t))); fclose(fp); } } } void init_daemon(void) { pid_t child1, child2; int i; child1 = fork(); if (child1 > 0) { exit(0); // 1. 創建子進程,終止父進程 } else if (child < 0) { perror("創建子進程失敗"); exit(1); } setsid(); // 2. 在子進程中創建新會話 chdir("/tmp"); // 3. 改變工作目錄到 /tmp umask(0); // 4. 重設文件創建掩碼 for(i = 0; i < NOFILE; ++i) { close(i); // 5. 關閉文件描述符 } return; } ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看