Linux -c- 多執行緒

瀟筱巰發表於2020-09-24

多程式

1. 多程式相關的理論概念
                程式:一個正在執行的程式,系統中就會產生一個對應的程式,動態的概念,在記憶體中執行
                程式:編譯器編譯得到的二進位制程式,靜態的概念,儲存在電腦的磁碟上
                父程式:你呼叫fork這個函式,建立出來的就是子程式,呼叫fork的程式就是父程式
                子程式:fork產生的都是子程式
                程式的ID號(pid):類似於程式的"身份證號"
                
                相關的命令:
                         ps  -elf   
                         檢視當前系統程式的執行狀態(PID --》程式ID號   CMD --》程式的名字)
                         
                cpu的排程策略:
                孤兒程式(殭屍程式): 父程式先於子程式退出,導致子程式的資源沒有人回收,子程式就變成孤兒程式
                         		  新版本的ubuntu,孤兒程式會被系統中一個叫做init的程式回收
                程式的組成: 棧,堆,資料段,程式碼段,程式控制塊(PCB--》process contrl block)
                程式控制塊: 指的是系統中定義的一個結構體,該結構體用於儲存程式執行時候的狀態資訊
                         struct  task_struct  
                         {
                                  pid_t pid; //當前程式的ID
                                  struct files_struct *files; 
                         //指向另外一個結構體陣列的,這個陣列專門用來存放你的程式中已經開啟的檔案資訊
                        };            
                程式組:多個程式組成的一個集合
2. linux提供的跟程式有關的介面函式
            (1)程式的建立
                pid_t fork(void);
                           返回值:  >0      父程式,此時返回值中儲存的就是建立成功的那個子程式的ID號
                                    ==0     子程式
                                    <0      失敗
             	特點(重點):一次呼叫兩次返回,跟我們以前學習的函式是不一樣,我們以前的函式都只能一次呼叫,返回一次
                                                 父子程式究竟誰先執行,誰後執行,是不確定的
              
            (2)程式的退出和回收
                   退出程式:
                            void exit(int status);  
                            void _exit(int status);
                                     引數:表示程式的退出值
                   跟return的區別
                           return是關鍵字,exit和_exit都是函式
                   exit和_exit的區別
                           exit結束程式的時候,會重新整理緩衝區,但是_exit不會
                           
                           重新整理緩衝區:
                                    遇到回車,或者return或者exit()都能重新整理緩衝區  
            (3)程式的回收
                   #include <sys/wait.h>
                   特點: 阻塞等待當前父程式,直到子程式退出為止
                   pid_t wait(int *wstatus);
                           返回值:成功  返回回收的那個子程式的ID號
                                        失敗  -1
                              引數:wstatus  --》用於儲存程式退出時候的狀態資訊(包括退出值,)
                                                            注意:exit的退出值僅僅只是退出狀態資訊的一部分
                   pid_t waitpid(pid_t pid, int *wstatus, int options);          
                           返回值:成功  返回回收的那個子程式的ID號
                                        失敗  -1
                              引數:pid --waitpid(-10002, );  我要回收程式組ID是10002裡面的某個程式
                                                    waitpid(-1,);              我要回收任意一個子程式
                                                    waitpid(0,);               我要回收本組中的任意一個子程式
                                                    waitpid(20000,);       我要指定回收ID號是20000的程式     
                                       options --》WNOHANG       
                 	非阻塞等待(父程式退出的時候,如果子程式還沒有結束,那麼父程式不會阻塞等待子程式,父程式會直接退出)
                                                          0                        阻塞等待
            (4)獲取當前程式的ID號,獲取父程式的ID號
                   pid_t getpid(void);
                             返回值:當前程式的ID號
                   pid_t getppid(void);
                             返回值:當前程式的父程式的ID號
                   pid_t getpgrp(void);  
                             返回值:當前程式所屬程式組的ID號 
3. 在一個程式中呼叫執行另外一個程式
         在一個程式中呼叫執行shell命令
                兩種實現方法:
                     (1)方法一: system()
                        eg:system("madplay  /1.mp3");
                     (2)方法二: exec函式族
           底層原理:這六個函式通過建立子程式,然後在子程式裡面執行你的命令或者程式
           
           int execl(const char *path, const char *arg, ...);
           返回值:失敗 -1
                         引數:path --》你要執行的程式或者命令的路徑名
                                   arg --》你要執行的程式或者命令的引數
           int execlp(const char *file, const char *arg, ...);
                        引數:file --》你要執行的程式或命令的名字(不需要寫路徑名)
                                  arg --》你要執行的程式或者命令的引數(以列表的形式逐一列舉)
           int execle(const char *path, const char *arg, ...  (char *) NULL, char * const envp[]);
                        引數:path --》你要執行的程式或者命令的路徑名
                                  arg --》你要執行的程式或者命令的引數
           int execv(const char *path, char *const argv[]);
           int execvp(const char *file, char *const argv[]);
           int execvpe(const char *file, char *const argv[], char *const envp[]);
                    l ---》引數必須以列表的形式逐一列舉
                    p ---》會去系統的環境變數中查詢要執行的命令或程式,只需要寫程式的名字即可
                    e ---》可以設定環境變數
                    v ---》引數用指標陣列存放
           echo  $PATH  //列印系統的環境變數PATH的值

相關文章