Linux c進程管理—建立進程 system、execl、execlp、fork

Linux c 進程管理:
 
1.      建立進程:
       system函數:
        int system(const char*filename);
                                                 創建獨立進程,擁有獨立的代碼空間,內存空間
                                                 等待新的進程執行完畢,system才返回.(阻塞)
         system:建立一個堵塞的新進程,新進程結束後,system才返回
 
         案例:
              使用system調用一個程序。
                    觀察進程ID。
                    觀察阻塞。
 
代碼:
text.c
 
#include<stdio.h>
#include<unistd.h>
 
void  main()
{
      printf(「%d\n」,getpid());    //打印當前進程id
      sleep(10);               //進程睡眠10秒
}
 
gcctext.c –o text
 
system.c
 
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
 
void  main()
{
     printf(「%d\n」,getpid());
     int r=system(「./text」);
     printf(「%d\n」,r);
}
 
gccsystem.c –o main
 
結論:
     新進程的返回值與system返回值有關係。
        任何進程的返回值:不要超過255。一個字節。
        system的返回值中8-15位存放返回碼(一個字節存放返回碼)
     要想獲得返回碼,則不能直接用system的返回值,要取返回值的8-15位的內容。
     Linux提供一個宏來獲取該值WEXITSTATUS(status)、包含在#include<sys/wait.h>中
 
代碼:
 
text.c
 
#include<stdio.h>
#include<unistd.h>
 
int  main()
{
      printf(「%d\n」,getpid());    //打印當前進程id
      sleep(10);             //進程睡眠10秒
      return 99;
}
 
gcctext.c –o text
 
system.c
 
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
 
void  main()
{
     printf(「%d\n」,getpid());
     int r=system(「./text」);
     printf(「%d\n」,WEXITSTATUS(r));
}
 
gccsystem.c –o main
 
 
 
 
 
 
 
popen函數:
   #include<stdio.h>
   函數原型:
   FILE * popen ( constchar * command , const char * type );
int pclose ( FILE * stream );
 
popen:建立子進程
在父子進程之間創建一個管道
command: 是一個指向以 NULL 結束的 shell 命令字符串的指針。這行命令將被傳到 bin/sh 並使用 -c 標誌,shell將執行這個命令。
type: 只能是讀或者寫中的一種,獲得的返回值(標準I/O 流)也具備和 type 相應的只讀或只寫類型。若是type 是 「r」 則文件指針鏈接到 command 的標準輸出;若是 type 是 「w」 則文件指針鏈接到command 的標準輸入。
返回值:
  若是調用成功,則返回一個讀或者打開文件的指針,若是失敗,返回NULL,具體錯誤要根據errno判斷
  int pclose (FILE*stream)
  參數說明:
  stream:popen返回的文件指針
  返回值:
  若是調用失敗,返回 -1
 
案例:
使用popen調用ls -l,而且創建一個管道讀取輸出
 
#include<stdio.h>
#include<unistd.h>
 
void main()
{
     char buf[1024];
     FILE *f=popen(「ls - l」,」r」);
     int fd=fileno(f);
     int r;
     while((r=read(fd,buf,1024))>0)
     {
            buf[r]=0;
          printf(「%s」,buf);
     }
     close(fd);
     pclose(f);
}
 
execlexecle:
          代替當前進程的代碼空間中的代碼數據,函數自己不建立新的進程。
 
excel函數:
int execl(const char * path,const char*arg,….);
第一個參數:替換的程序
第二個參數…..:命令行
                      命令行格式:命令名 選項參數
                      命令行結尾必須空字符串結尾
 
案例:
                     使用exec執行一個程序。
                     體會:*是否建立新的進程?沒有
                              *體會execl的參數的命令行的格式
                              *體會execl與execlp的區別(execl只當前路徑)(不是當前路徑必須加絕對路徑)
                                                               execlp使用系統的搜索路徑
                               *體會execl替換當前進程的代碼
 
代碼:
 
text.c
 
#include<stdio.h>
#include<unistd.h>
 
void  main()
{
      printf(「%d\n」,getpid());    //打印當前進程id
      sleep(10);             //進程睡眠10秒
   
}
 
gcctext.c –o text
 
 
 
 
exec.c
 
#include<stdio.h>
#include<unistd.h>
 
 
void  main()
{
       printf(「main::%d\n」,getpid());
       int r=excel(「./text」,」text」,NULL);
       //int r=excel(「/bin/ls」,」ls」,」-l」,NULL);
       //int r=excelp(「ls」,」ls」,」-l」,NULL);
       printf(「結束:%d\n」,r);
}
 
總結:
程序運行後,兩個打印進程id是同樣,則excel和execlp不建立新的進程。
最後的打印結束的語句不能執行,由於excel和excelp是將新的程序的代碼替換到該程序的代碼空間中了。
兩個函數的最後一個參數必須爲0或NULL
函數的第一個參數是可執行程序的路徑,第二個參數纔是執行的命令
 
 
fork函數:
函數原型:
         pid_t  fork(); //1.建立進程
                     //2.新進程的代碼是什麼:克隆父進程的代碼
                                                        並且克隆了執行的位置.(從父進程複製過來的代碼,fork以前的代碼不會再子進程中執行,子進程只會執行從父進程複製過來的fork之後的代碼)
                     //3.在子進程不調用fork因此返回值=0;(pid=0爲子進程的)
                                    //4.父子進程同時執行.
 
例子代碼:
#include<stdio.h>
#include<unistd.h>
 
void  main()
{
      printf(「建立進程以前\n」);
      int pid=fork();
      printf(「創進程以後%d\n」,pid);
}
 
雖然子進程的代碼是克隆父進程的,但咱們也能夠把子進程要執行的代碼和父進程要執行的代碼分開。
 
例子:
#include<stdio.h>
#include<unistd.h>
 
voidmain()
{
      printf(「建立進程以前:\n」);
      int pid=fork();
      if(pid==0)
      {
           printf(「子進程:\n」);
      }
      else
      {
           printf(「父進程:\n」);
      }
}
相關文章
相關標籤/搜索