Linux是一個多任務的操作系統,系統上同時運行著多個進程,正在執行的一個或多個相關進程稱為一個作業。使用作業控制,用戶可以同時運行多個作業,並在需要時在作業之間進行切換。本章詳細介紹進程管理及作業控制的命令,包括啟動進程、查看進程、調度作業的命令。
進程及作業的概念
Linux是一個多用戶多任務的操作系統。多用戶是指多個用戶可以在同一時間使用計算機系統;多任務是指Linux可以同時執行幾個任務,它可以在還未執行完一個任務時又執行另一項任務。
操作系統管理多個用戶的請求和多個任務。大多數系統都只有一個CPU和一個主存,但一個系統可能有多個二級存儲磁盤和多個輸入/輸出設備。操作系統管理這些資源並在多個用戶間共享資源,當您提出一個請求時,給您造成一種假象,好象系統只被您獨自占用。而實際上操作系統監控著一個等待執行的任務隊列,這些任務包括用戶作業、操作系統任務、郵件和打印作業等。操作系統根據每個任務的優先級為每個任務分配合適的時間片,每個時間片大約都有零點幾秒,雖然看起來很短,但實際上已經足夠計算機完成成千上萬的指令集。每個任務都會被系統運行一段時間,然後掛起,系統轉而處理其他任務;過一段時間以後再回來處理這個任務,直到某個任務完成,從任務隊列中去除。
Linux系統上所有運行的東西都可以稱之為一個進程。每個用戶任務、每個系統管理守護進程,都可以稱之為進程。Linux用分時管理方法使所有的任務共同分享系統資源。我們討論進程的時候,不會去關心這些進程究竟是如何分配的,或者是內核如何管理分配時間片的,我們所關心的是如何去控制這些進程,讓它們能夠很好地為用戶服務。
進程的一個比較正式的定義是:在自身的虛擬地址空間運行的一個單獨的程序。進程與程序是有區別的,進程不是程序,雖然它由程序產生。程序只是一個靜態的指令集合,不占系統的運行資源;而進程是一個隨時都可能發生變化的、動態的、使用系統運行資源的程序。而且一個程序可以啟動多個進程。
Linux操作系統包括三種不同類型的進程,每種進程都有自己的特點和屬性。
交互進程——由一個shell啟動的進程。交互進程既可以在前台運行,也可以在後台運行。
批處理進程——這種進程和終端沒有聯系,是一個進程序列。
監控進程(也稱守護進程)——Linux系統啟動時啟動的進程,並在後台運行。
上述三種進程各有各的作用,使用場合也有所不同。
進程和作業的概念也有區別。一個正在執行的進程稱為一個作業,而且作業可以包含一個或多個進程,尤其是當使用了管道和重定向命令。例如“nroff -man ps.1grep killmore”這個作業就同時啟動了三個進程。
作業控制指的是控制正在運行的進程的行為。比如,用戶可以掛起一個進程,等一會兒再繼續執行該進程。shell將記錄所有啟動的進程情況,在每個進程過程中,用戶可以任意地掛起進程或重新啟動進程。作業控制是許多shell(包括bash和tcsh)的一個特性,使用戶能在多個獨立作業間進行切換。
一般而言,進程與作業控制相關聯時,才被稱為作業。
在大多數情況下,用戶在同一時間只運行一個作業,即它們最後向shell鍵入的命令。但是使用作業控制,用戶可以同時運行多個作業,並在需要時在這些作業間進行切換。這會有什麼用途呢?例如,當用戶編輯一個文本文件,並需要中止編輯做其他事情時,利用作業控制,用戶可以讓編輯器暫時掛起,返回shell提示符開始做其他的事情。其他事情做完以後,用戶可以重新啟動掛起的編輯器,返回到剛才中止的地方,就象用戶從來沒有離開編輯器一樣。這只是一個例子,作業控制還有許多其他實際的用途。
啟動進程
鍵入需要運行的程序的程序名,執行一個程序,其實也就是啟動了一個進程。在Linux系統中每個進程都具有一個進程號,用於系統識別和調度進程。啟動一個進程有兩個主要途徑:手工啟動和調度啟動,後者是事先進行設置,根據用戶要求自行啟動。
手工啟動
由用戶輸入命令,直接啟動一個進程便是手工啟動進程。但手工啟動進程又可以分為很多種,根據啟動的進程類型不同、性質不同,實際結果也不一樣,下面分別介紹。
1. 前台啟動
這或許是手工啟動一個進程的最常用的方式。一般地,用戶鍵入一個命令“ls –l”,這就已經啟動了一個進程,而且是一個前台的進程。這時候系統其實已經處於一個多進程狀態。或許有些用戶會疑惑:我只啟動了一個進程而已。但實際上有許多運行在後台的、系統啟動時就已經自動啟動的進程正在悄悄運行著。還有的用戶在鍵入“ls –l”命令以後趕緊使用“ps –x”查看,卻沒有看到ls進程,也覺得很奇怪。其實這是因為ls這個進程結束太快,使用ps查看時該進程已經執行結束了。如果啟動一個比較耗時的進程:
find / -name fox.jpg
然後再把該進程掛起,使用ps查看,就會看到一個find進程在裡面。
2. 後台啟動
直接從後台手工啟動一個進程用得比較少一些,除非是該進程甚為耗時,且用戶也不急著需要結果的時候。假設用戶要啟動一個需要長時間運行的格式化文本文件的進程。為了不使整個shell在格式化過程中都處於“癱瘓”狀態,從後台啟動這個進程是明智的選擇。
[例1]
$ troff –me notes > note_form &
[1] 4513
$
由上例可見,從後台啟動進程其實就是在命令結尾加上一個&號。鍵入命令以後,出現一個數字,這個數字就是該進程的編號,也稱為PID,然後就出現了提示符。用戶可以繼續其他工作。
上面介紹了前、後台啟動的兩種情況。實際上這兩種啟動方式有個共同的特點,就是新進程都是由當前shell這個進程產生的。也就是說,是shell創建了新進程,於是就稱這種關系為進程間的父子關系。這裡shell是父進程,而新進程是子進程。一個父進程可以有多個子進程,一般地,子進程結束後才能繼續父進程;當然如果是從後台啟動,那就不用等待子進程結束了。
一種比較特殊的情況是在使用管道符的時候。例如:
nroff -man ps.1grep killmore
這時候實際上是同時啟動了三個進程。請注意是同時啟動的,所有放在管道兩邊的進程都將被同時啟動,它們都是當前shell的子程序,互相之間可以稱為兄弟進程。
以上介紹的是手工啟動進程的一些內容,作為一名系統管理員,很多時候都需要把事情安排好以後讓其自動運行。因為管理員不是機器,也有離開的時候,所以有些必須要做的工作而恰好管理員不能親自操作,這時候就需要使用調度啟動進程了。
調度啟動
有時候需要對系統進行一些比較費時而且占用資源的維護工作,這些工作適合在深夜進行,這時候用戶就可以事先進行調度安排,指定任務運行的時間或者場合,到時候系統會自動完成這一切工作。
要使用自動啟動進程的功能,就需要掌握以下幾個啟動命令。
at命令
用戶使用at命令在指定時刻執行指定的命令序列。也就是說,該命令至少需要指定一個命令、一個執行時間才可以正常運行。at命令可以只指定時間,也可以時間和日期一起指定。需要注意的是,指定時間有個系統判別問題。比如說:用戶現在指定了一個執行時間:凌晨3:20,而發出at命令的時間是頭天晚上的20:00,那麼究竟是在哪一天執行該命令呢?如果用戶在3:20以前仍然在工作,那麼該命令將在這個時候完成;如果用戶3:20以前就退出了工作狀態,那麼該命令將在第二天凌晨才得到執行。下面是at命令的語法格式:
at [-V] [-q 隊列] [-f 文件名] [-mldbv] 時間
at -c 作業 [作業...]
at允許使用一套相當復雜的指定時間的方法,實際上是將POSIX.2標准擴展了。它可以接受在當天的hh:mm(小時:分鐘)式的時間指定。如果該時間已經過去,那麼就放在第二天執行。當然也可以使用midnight(深夜),noon(中午),teatime(飲茶時間,一般是下午4點)等比較模糊的詞語來指定時間。用戶還可以采用12小時計時制,即在時間後面加上AM(上午)或者PM(下午)來說明是上午還是下午。
也可以指定命令執行的具體日期,指定格式為month day(月 日)或者mm/dd/yy(月/日/年)或者dd.mm.yy(日.月.年)。指定的日期必須跟在指定時間的後面。
上面介紹的都是絕對計時法,其實還可以使用相對計時法,這對於安排不久就要執行的命令是很有好處的。指定格式為:now + count time-units ,now就是當前時間,time-units是時間單位,這裡可以是 minutes(分鐘)、hours(小時)、days(天)、weeks(星期)。count是時間的數量,究竟是幾天,還是幾小時,等等。
還有一種計時方法就是直接使用today(今天)、tomorrow(明天)來指定完成命令的時間。下面通過一些例子來說明具體用法。
[例2] 指定在今天下午5:30執行某命令。假設現在時間是中午12:30,1999年2月24日,其命令格式如下:
at 5:30pm
at 17:30
at 17:30 today
at now + 5 hours
at now + 300 minutes
at 17:30 24.2.99
at 17:30 2/24/99
at 17:30 Feb 24
以上這
[例2] 指定在今天下午5:30執行某命令。假設現在時間是中午12:30,1999年2月24日,其命令格式如下:
at 5:30pm
at 17:30
at 17:30 today
at now + 5 hours
at now + 300 minutes
at 17:30 24.2.99
at 17:30 2/24/99
at 17:30 Feb 24
以上這