Linux 進程與訊號

來源:互聯網
上載者:User

Linux和Unix一樣,有一個虛擬記憶體系統,能夠把程式碼和資料以記憶體頁面的形式放到硬碟的一個地區中,所以

Linux可以管理的進程比實體記憶體所能容納的要多得多。

進程表

查看進程

ps -ef

TTY 一列顯示了進程是從那個終端啟動的。TIME一列是進程到目前為止所佔用的CPU時間。

CMD一列顯示啟動進程使用的命令。STAT一列用來表明進程的當前代碼。

STAT代碼解釋:

S    睡眠,通常是等待某事件發生,如訊號或有輸入可用

R    運行,嚴格來說是可運行,即在運行隊列當中,處於正在執行或即將執行狀態

D    不可中斷睡眠(等待)。通常是在等待輸入輸出完成

T    停止。

Z    殭屍進程

N    低優先順序任務

W    分頁(不適用於2.6開始的版本)

s    進程會話期首進程

+    進程屬於前台進程組

l    多線程進程

<    高優先順序進程

啟動新進程

#include<stdlib.h>

int system(const char *string);

system函數的作用是,運行以字串參數的形式傳遞給它的命令並等待該命令的完成。命令的執行情況就如同在

shell中執行下列命令

$ sh -c string

1.替換進程映像

#include<unistd.h>int execl(const char *path, const char *arg0 , ... , (char *)0);int execlp(const char *file , const char *arg0, ... , (char *)0);int execle(const char *path , const char *arg0 , ... , (char *)0 , char *const envp[] );int execv(const char *path, const char *arg0 , ... , (char *)0);int execvp(const char *file , const char *arg0, ... , (char *)0);int execve(const char *path , const char *arg0 , ... , (char *)0 , char *const envp[] );

這些函數可以分為兩類,execl,execlp和execle的參數個數是可變的,參數以一個null 指標結構結束。

以字母P結尾的函數通過搜尋path環境變數來尋找程式的可執行檔的路徑。

2.複製進程映像

#include<sys/types.h>#include<unistd.h>pid_t fork(void);

子進程中的fork調用返回的是0,父子進程可以通過這一點來判斷究竟誰是父進程,誰是子進程。

經過fork調用後,父進程返回一個新的進程PID,子進程返回0。

#include <sys/types.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>int main(){    pid_t pid;    char *message;    int n;    printf("fork program starting\n");    pid = fork();    switch(pid)     {    case -1:        perror("fork failed");        exit(1);    case 0:        message = "This is the child";        n = 5;        break;    default:        message = "This is the parent";        n = 3;        break;    }    for(; n > 0; n--) {        puts(message);        sleep(1);    }    exit(0);}

等待一個進程

#include<sys/types.h>#include<sys/wait.h>pid_t wait(int *stat_loc);

wait系統調用將父進程知道它的子進程結束為止。這個調用返回子進程的PID,它通常是已經結束啟動並執行子進程的PID。

我們可以用sys/wait.h檔案定義的宏來解釋狀態資訊。如表11-2所示

                                   宏                                                   說明

WIFEXITED(stat_val)                                          如果子進程正常結束,它就取一個非零值。

WEXITSTATUC(stat_val)                                   如果WIFEXITED非零,它就返回子進程的退出碼。

WIFSIGNALED(stat_val)                                    如果子進程因為一個未捕獲的訊號而終止,它就取一個非零值。

WTERMSIG(stat_val)                                         如果WIFSIGNALED非零,它返回一個訊號代碼。

WIFSTOPPED(stat_val)                                    如果子進程意外終止,它就取一個非零值。

WSTOPSIG(stat_val)                                         如果WIFSTOPPED非零,它返回一個訊號代碼

#include <sys/types.h>#include <sys/wait.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>int main(){    pid_t pid;    char *message;    int n;    int exit_code;    printf("fork program starting\n");    pid = fork();    switch(pid)     {    case -1:        exit(1);    case 0:        message = "This is the child";        n = 5;        exit_code = 37;        break;    default:        message = "This is the parent";        n = 3;        exit_code = 0;        break;    }    for(; n > 0; n--) {        puts(message);        sleep(1);    }/*  This section of the program waits for the child process to finish.  */    if(pid) {        int stat_val;        pid_t child_pid;        child_pid = wait(&stat_val);        printf("Child has finished: PID = %d\n", child_pid);        if(WIFEXITED(stat_val))            printf("Child exited with code %d\n", WEXITSTATUS(stat_val));        else            printf("Child terminated abnormally\n");    }    exit (exit_code);}

殭屍進程

用fork來建立進程確實很有用,但你必須清楚子進程的運行情況。子進程終止時,它與父進程之間的關聯還會保持。

直到父進程也正常終止或父進程調用wait才告結束。因此,進程表中代表子進程的表項不會立刻釋放。雖然子進程

已經不再運行,但它依然存在系統中,因為它的退出碼還需要儲存起來,以備父進程今後的wait調用使用。這時它

成為一個死進程或殭屍進程。

還有一個系統調用可以用來等待子進程的結束,它是waitpid函數。你可以用它來等待某個特定的進程結束。

#include<sys/types.h>

#include<sys/wait.h>

pid_t waitpid(pid_t pid, int *stat_loc , int options);

輸入輸出重新導向

#include <stdio.h>#include <ctype.h>#include <stdlib.h>int main(){    int ch;    while((ch = getchar()) != EOF) {        putchar(toupper(ch));    }    exit(0);}

/*  This code, useupper.c, accepts a file name as an argument    and will respond with an error if called incorrectly.  */#include <unistd.h>#include <stdio.h>#include <stdlib.h>int main(int argc, char *argv[]){    char *filename;    if(argc != 2) {        fprintf(stderr, "usage: useupper file\n");        exit(1);    }    filename = argv[1];/*  That done, we reopen the standard input, again checking for any errors as we do so,    and then use execl to call upper.  */    if(!freopen(filename, "r", stdin)) {        fprintf(stderr, "could not redirect stdin to file %s\n", filename);        exit(2);    }    execl("./upper", "upper", 0);/*  Don't forget that execl replaces the current process;    provided there is no error, the remaining lines are not executed.  */    perror("could not exec ./upper");    exit(3);}

freopen()函數負責把一個流重新導向到另外一個流。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.