Linux 進程

基本概念

進程是指正在運行的程序,一個程序中可以包含多個進程,一個進程可能包含一個或多個線程。
每一個進程都有一個唯一的ID,簡稱pid,進程的ID在某一固定時刻是唯一的。
內核運行的第一個進程的ID是1,也就是內核的init程序,這個是唯一的。
默認情況下,進程pid的最大值爲32768,這個值是可以修改的。
進程的(ID)分配是嚴格線性分配的,直到pid到了最大值,纔會重新分配已經使用過的ID。
除了init進程,其他進程都是由其他進程創建的,創建新進程的進程叫父進程,新進程叫子進程。
在Linux中,使用top命令可以查看進程,kill結束某一進程。

獲取進程ID

獲取進行ID有兩個函數,分別爲pid_t getpid(void);pid_t getppid(void);
其中getpid爲獲取進程號,getppid爲獲取當前進程的父進程號;
這兩個函數的返回值均爲進程號。

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

main()
{
    pid_t idp, ids;

    idp = getppid();						//獲取父進程號
    printf("ppid = %d \n", idp);

    ids = getpid();							//獲取子進程號
    printf("pid = %d \n", ids);

    while(1);    

}

exec系列函數

The exec() family of functions replaces the current process image with a new process image.
exec系列相關的函數有

int execl(const char *path, const char *arg, ...
                       /* (char  *) NULL */);
int execlp(const char *file, const char *arg, ...
                       /* (char  *) NULL */);
int execle(const char *path, const char *arg, ...
                       /*, (char *) NULL, char * const envp[] */);
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[]);

這一系列函數的區別在於exec後面所跟的字母不一樣,所傳入的參數也有不同的要求。
“l”表示參數以列表的形式提供
“v”表示參數以數組的方式提供
“p”表示函數的第一個參數是*path,需要以絕對路徑來提供程序的路徑,也可以以當前目錄作爲目標
“e”表示爲程序提供新的環境變量

*path表示要啓動的程序名或路徑名,
arg表示啓動程序所帶的參數, 一般第一個參數爲需要執行的命令名
執行成功返回0,執行失敗返回-1
使用不同的exec函數執行 ls -a 命令

execl("/bin/ls","ls","-a",NULL)
execlp("ls","ls","-a",NULL)
execle("/bin/ls","ls","-a",NULL,NULL)
char *arg[] = {"ls", "-a", NULL};

execv("/bin/ls",arg)
execvp("ls",arg)
execve("/bin/ls",arg,NULL)

fork函數

在 linux 中可以使用 fork 創建和當前進程一樣的進程,新的進程叫子進程,原來的進程叫父進程。

函數原型:pid_t fork();
傳入參數:none
返回值:執行成功時,子進程pid返回給父進程,0返回給子進程;出現錯誤時返回-1給父進程。執行失敗的唯一情況是內存不夠或id號用光。

當函數執行成功時,子進程中的資源統計信息會被清零;掛起的信號會被清除,將不會被寄存;所有的文件鎖也不會被子進程繼承。

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

main()
{
    pid_t pid;
    int i = 100;

    pid = fork();       
    if(pid == -1){                      //fork執行失敗
        printf("fork failed \n");
        return 1;
    }

    else if(pid)                        //父進程中,返回的pid爲子進程pid,執行的是這一段程序
    {
        i++;
        printf("i = %d in father process!\n", i);
        printf("the father return value is %d\n", pid);
        printf("The father pid is %d\n", getpid());
        printf("The father ppid is %d\n", getppid());
        while(1);
    }

    else                                //子進程中,返回的pid爲0,執行這一點程序
    {
        i++;
        printf("i = %d in child process!\n", i);
        printf("the child return value is %d\n", pid);
        printf("The child pid is %d\n", getpid());
        printf("The child ppid is %d\n", getppid());
        while(1);
        
    }
    
    return 0;

}

運行這段程序,兩次打印的i都爲101,所以,子進程可以使用父進程中定義的變量,和父進程中的變量卻是不同的變量。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章