linux系統編程之進程(五):終端、作業控制與守護進程

來源:互聯網
上載者:User

一、終端的概念

在UNIX系統中,使用者通過終端登入系統後得到一個Shell進程,這個終端成為Shell進程的控制終端(Controlling Terminal),控制終端是儲存在PCB中的資訊,而我們知道fork會複製PCB中的資訊,因此由Shell進程啟動的其它進程的控制終端也是這個終端。預設情況下(沒有重新導向),每個進程的標準輸入、標準輸出和標準錯誤輸出都指向控制終端,進程從標準輸入讀也就是讀使用者的鍵盤輸入,進程往標準輸出或標準錯誤輸出寫也就是輸出到顯示器上。在控制終端輸入一些特殊的修飾鍵可以給前台進程發訊號,例如Ctrl-C表示SIGINT,Ctrl-\表示SIGQUIT。


每個進程都可以通過一個特殊的裝置檔案/dev/tty訪問它的控制終端。事實上每個終端裝置都對應一個不同的裝置檔案,/dev/tty提供了一個通用的介面,一個進程要訪問它的控制終端既可以通過/dev/tty也可以通過該終端裝置所對應的裝置檔案來訪問。ttyname函數可以由檔案描述符查出對應的檔案名稱,該檔案描述符必須指向一個終端裝置而不能是任意檔案。在linux上的命令tty 也可以查看到當前的終端。

比如我們在圖形介面下開啟一個終端可能是/dev/pts/0, 第二個可能是/dev/pts/1 ...(網路終端)

而切換到字元介面下可能是/dev/tty1 ...(虛擬終端)


二、作業控制

事實上,Shell分前後台來控制的不是進程而是作業(Job)或者進程組(Process Group)。一個前台作業可以由多個進程組成,一個後台作業也可以由多個進程組成,Shell可以同時運行一個前台作業和任意多個後台作業,這稱為作業控制(JobControl)。例如用以下命令啟動5個進程(這個例子出自APUE):

$ proc1 | proc2 &

$ proc3 | proc4 | proc5


其中proc1和proc2屬於同一個後台進程組,proc3、proc4、proc5屬於同一個前台進程組,Shell進程本身屬於一個單獨的進程組。這些進程組的控制終端相同,它們屬於同一個Session,一個Session與一個控制終端相關。當使用者在控制終端輸入特殊的修飾鍵(例如Ctrl-C)時,核心會發送相應的訊號(例如SIGINT)給前台進程組的所有進程。各進程、進程組、Session的關係如所示。


在上面的例子中,proc3、proc4、proc5被Shell放到同一個前台進程組,其中有一個進程是該進程組的Leader,Shell調用wait等待它們運行結束。一旦它們全部運行結束,Shell就調用tcsetpgrp函數將自己提到前台繼續接受命令。但是注意,如果proc3、proc4、proc5中的某個進程又fork出子進程,子進程也屬於同一進程組,但是Shell並不知道子進程的存在,也不會調用wait等待它結束。換句話說,proc3 | proc4
| proc5是Shell的作業,而這個子進程不是,這是作業和進程組在概念上的區別。一旦作業運行結束,Shell就把自己提到前台,如果原來的前台進程組還存在(如果這個子進程還沒終止),則它自動變成後台進程,被init進程接管。


三、守護進程

守護進程是在後台運行不受控端控制的進程,通常情況下守護進程在系統啟動時自動運行,使用者關閉終端視窗或登出也不會影響守護進程的運行,只能kill掉。守護進程的名稱通常以d結尾,比如sshd、xinetd、crond等

我們用ps axj命令查看系統中的進程,凡是TPGID(前台進程組ID)一欄寫著-1的都是沒有控制終端的進程,或者TTY一欄為?的,也就是守護進程。


四、建立守護進程步驟

調用fork(),建立新進程,它會是將來的守護進程
在父進程中調用exit,保證子進程不是進程組組長
調用setsid建立新的會話期
將目前的目錄改為根目錄
將標準輸入、標準輸出、標準錯誤重新導向到/dev/null


成功調用setsid函數的結果是:

建立一個新的Session,當前進程成為Session Leader,當前進程的id就是Session的id。

建立一個新的進程組,當前進程成為進程組的Leader,當前進程的id就是進程組的id。

如果當前進程原本有一個控制終端,則它失去這個控制終端,成為一個沒有控制終端的進程。


樣本程式:

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/*************************************************************************
    > File Name: process_.c
    > Author: Simba
    > Mail: dameng34@163.com
    > Created Time: Sat 23 Feb 2013 02:34:02 PM CST
 ************************************************************************/
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>

#define ERR_EXIT(m) \
    do { \
        perror(m); \
        exit(EXIT_FAILURE); \
    } while(0)

int setup_daemon(int, int);
/* 守護進程一直在後台運行且不控制終端 */
int main(int argc, char *argv[])
{
    //  daemon(0, 0)
    setup_daemon(0, 0);
    printf("test ... \n"); // 無輸出
    for(;;) ;
    return 0;
}

int setup_daemon(int nochdir, int noclose)
{
    pid_t pid;
    pid = fork();
    if (pid == -1)
        ERR_EXIT("fork error");
    if (pid > 0)
        exit(EXIT_SUCCESS);
    /* 調用setsid的進程不能為進程組組長,故fork之後將父進程退出 */
    setsid(); // 子進程調用後產生一個新的會話期
    if (nochdir == 0)
        chdir("/"); //更改目前的目錄為根目錄
    if (noclose == 0)
    {
        int i;
        for (i = 0; i < 3; ++i)
            close(i);
        open("/dev/null", O_RDWR); // 將標準輸入,標準輸出等都重新導向到/dev/null
        dup(0);
        dup(0);
    }

    return 0;
}

執行程式再ps axj 一下:

simba@ubuntu:~/Documents/code/linux_programming/APUE/process$ ./daemon 
simba@ubuntu:~/Documents/code/linux_programming/APUE/process$ ps axj
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND

...........................................................................................................................

 1  7678  7678  7678 ?           -1 Rs    1000   0:03 ./daemon

可以看出守護進程的ID也是進程組的ID,也是會話期的ID,此外這個會話期沒有前台進程組。


五、使用daemon函數實現守護進程

功能:建立一個守護進程

原型:int daemon(int nochdir, int noclose);
參數:
nochdir:=0將目前的目錄更改至“/”
noclose:=0將標準輸入、標準輸出、標準錯誤重新導向至“/dev/null”



參考:《linux c 編程一站式學習》、《APUE》

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.