Các tiến trình

Một phần của tài liệu Giáo trình sử dụng quản trị và lập trình UNIX LINUX (Trang 43 - 48)

a. Khái niệm tiến trình

Trong UNIX, một tiến trình (process) là một lệnh đang tiến hành, hay nói rộng hơn là một chương trình user bất kỳ đang tiến hành. Trước khi lệnh đang tiến hành một chương trình được kích hoạt, chương trình chỉ là một tệp đĩa nằm trong cấu trúc cây của UNIX, ví dụ tệp cat hoặc tệp a.out.

Khi ta kích hoạt chương trình đó bằng một lệnh, ví dụ: % a.out

thì một tiến trình được sinh ra trong bộ nhớ RAM ngay trước khi việc đang tiến hành chương trình đó bắt đầu. Cấu trúc vật lý của tiến trình bao gồm những thành phần cơ bản sau đây:

1- số định danh của tiến trình (pid), một số nguyên và là tên duy nhất được gán cho tiến trình từ khi nó sinh ra

2- số định danh của user (uid), số này nằm trong tệp /etc/passwd

3- số định danh của nhóm user (gid), số này cũng nằm trong tệp /etc/passwd 4- các mảng (segment) khác nhau, bao gồm mảng mã và mảng dữ liệu user: + mảng mã chứa các chỉ thị của chương trình. Những chỉ thị này có dạng nhị phân nếu chương trình là một tệp khả thi, hoặc có dạng văn bản nếu chương trình là một tệp lệnh shell (shell script). Mảng mã có kích thước cố định và không thay đổi được trong khi tiến hành. Nếu tiến trình được khai báo là hồi quy (reentrant) khi biên dịch liên kết (linking) thì nghĩa rằng nó có thể được dùng chung (nhưng chỉ đọc) cho nhiều tiến trình. Mảng mã được mặc định là hồi quy.

+ mảng dữ liệu user chứa các dữ liệu toàn cục (global) của chương trình, trong đó những dữ liệu nào không được user khởi tạo thì UNIX sẽ chuyển thành 0. Mảng dữ liệu user có kích thước thay đổi tuỳ theo sự cấp phát (allocation) hoặc giải phóng linh động (dynamic liberation) bộ nhớ do user thúc đẩy trong khi tiến hành chương trình, ví dụ bằng các hàm malloc, calloc, realloc hoặc free của ngôn ngữ C. 5- ngăn xếp (stack)

6- các thông tin về hệ thống như: + đường dẫn tuyệt đối của thư mục hiện hành

+ tên terminal đã kích hoạt chương trình + mức ưu tiên của tiến trình

+ thời gian thực hiện tiến trình + nội dung các thanh ghi

Cấu trúc bao gồm các thành phần nói trên của tiến trình sẽ xác định môi trường tiến trình hoặc ảnh tiến trình. Sau khi chúng được xây dựng xong thì chương trình bắt đầu thật sự được tiến hành một cách tuần tự, hết chỉ thị này đến chỉ thị khác.

Cách duy nhất để kích hoạt một tiến trình UNIX là gọi đến hàm hệ thống fork. Khi đó pid được ghi vào bảng các tiến trình bao gồm dữ liệu về mọi tiến trình đang tồn tại. Khi tiến trình kết thúc thì dữ liệu về nó bị xoá khỏi bảng này. Việc tiến hành một chương trình user hoặc một lệnh shell ngoại trú đều bắt buộc phải sinh ra một tiến trình mới, tồn tại cho đến khi hoàn thành chương trình.

b. Tiến trình mặt trước

Tất cả các tiến trình ta thấy được cho tới lúc này đều là những tiến trình mặt trước (foreground); nghĩa là khi đưa ra một lệnh hoặc một chương trình, ta phải chờ kết thúc xong tiến trình tương ứng và dấu nhắc của Shell lại xuất hiện để có thể đưa ra một lệnh mới.

Ta có thể thu ngắn vòng đời của một tiến trình bằng cách nhấn phím <DELETE>, hoặc các phím ^C hoặc ^\

Tất cả các tiến trình này được xử lý tuần tự và do đó cũng gọi là đồng bộ (synchronous).

c. Tiến trình hậu trường

Ta gõ ký tự “&” trước khi nhấn phím <RETURN> để thực hiện một tiến trình trong hậu trường (background). Ví dụ:

% find / -name tệp -print &<RETURN> Ta sẽ thấy xuất hiện một số:

2735

số này chính là số định danh của tiến trình (pid) vừa mới được tạo ra. Chú ý:

Trong C Shell, ta còn nhận được một số đứng trước số của tiến trình, đó là số hiệu của "job": [1] 2735

Ngay sau đó và trước khi kết thúc việc tiến hành lệnh này ở hậu trường, ta lại thấy dấu nhắc %, nhờ vậy có thể kích hoạt việc tiến hành một chương trình khác.

Lệnh find vừa được kích hoạt hiện đang tiến hành ở hậu trường.

Chính sự hiện diện của dấu “&” ở sau lệnh find và trên cùng dòng lệnh, đã thông báo cho tiến trình sắp được tạo ra biết rằng sẽ tiến hành trong hậu trường.

Chương trình có thể kích hoạt tiếp theo sẽ là chính nó, không phụ thuộc vào việc tiến hành ở mặt trước hay hậu trường.

Hai việc tiến hành sẽ được tiến hành song song, nhưng thực ra được xử lý theo cách đa nhiệm. Ta cũng nói rằng mỗi nhiệm vụ tạo ra như vậy sẽ chạy một cách không đồng bộ (asynchronous).

Chú ý:

Khi kích hoạt nhiều việc tiến hành đồng thời, ta quan tâm sao cho các luồng dữ liệu ra không đổ tất cả lên màn hình, vì điều đó có thể dẫn đến sự nhầm lẫn. Như vậy nên chỉnh hướng để mỗi luồng đi ra một cổng riêng, không chuẩn. Ví dụ trong C Shell:

% find / -name tệp_tìm_kiếm -print >&\ tệp_ra & (adsbygoogle = window.adsbygoogle || []).push({});

Trong trường hợp này, hai luồng dữ liệu ra, tức là những thông tin được yêu cầu và những thông báo lỗi sẽ được chỉnh hướng về tệp đĩa "tệp_ra"

d. Lệnh wait

Lệnh wait không có đối số sẽ bắt máy phải chờ kết thúc mọi tiến trình hậu trường mới cho nhận lệnh tiếp theo:

% wait<RETURN>

Sau lệnh này, dấu nhắc Shell không xuất hiện trở lại chừng nào tất cả tiến trình hậu trường chưa kết thúc .

Chú ý:

Ta có thể hủy bỏ lệnh wait bằng phím <DEL> hoặc ^C. Các tiến trình hậu trường vẫn tiếp tục tiến hành cả sau khi hủy bỏ lệnh wait.

L nh wait c a UNIX SYSTEM Vệ

Ta có thể gõ sau lệnh wait một đối số là pid của một tiến trình, ví dụ: % wait 9374

Trong trường hợp này, ta chỉ phải chờ kết thúc tiến trình số 9374.

e. Hủy bỏ một tiến trình hậu trường

Để hủy bỏ một tiến trình hậu trường, ta dùng lệnh kill với đối số là pid của tiến trình, ví dụ:

% kill 9374

Ghi nhớ rằng đôi khi cần sử dụng tuỳ chọn -9 để kết thúc một tiến trình, ví dụ: % kill -9 9374

Tuỳ chọn -9 là bắt buộc để hủy một tiến trình cha của phiên làm việc. Những người có quyền hủy một tiến trình gồm có:

-user đã kích hoạt tiến trình đó -superuser

f. Trạng thái của tiến trình

Khi một tiến trình kết thúc, nó trả lại một giá trị được gọi là trạng thái (status). Giá trị này sẽ là 0 nếu tiến trình kết thúc đúng, nếu sai thì sẽ khác 0. Giá trị status được định vị trong một biến xác định trước và được ký hiệu bởi:

dấu ? trong Bourne Shell từ "status" trong C Shell

Ví dụ:

Giả thiết rằng "người" là tên của một tệp tồn tại trong thư mục hiện thời và rằng tệp "ma" không tồn tại. Ta có:

trong Bourne Shell: $ cat người tệp_ra $ echo $?

0 trong C Shell:

% cat ma >& tệp_ra % echo $status 1

g. Mức ưu tiên của tiến trình

Một user thông thường có thể hiệu chỉnh độ ưu tiên của một tiến trình mà user đó kiểm soát, bằng cách giảm độ ưu tiên so với giá trị mặc định. Người sử dụng tối cao có thể tăng hoặc giảm độ ưu tiên của mọi tiến trình.

Để hiệu chỉnh độ ưu tiên này ta có lệnh nice:

1- Trong Bourne Shell

một tiến trình có độ ưu tiên là 10 (giá trị mặc định) + một user có thể giảm nó đi bằng dạng lệnh:

$ nice -15 a.out (adsbygoogle = window.adsbygoogle || []).push({});

tuỳ chọn n của "-n" có thể thay đổi từ 0 tới 20

+ người sử dụng tối cao sẽ có thể làm tăng độ ưu tiên này dưới dạng lệnh: $ nice --10 find / -name tệp -print

2- Trong C Shell

một tiến trình có độ ưu tiên theo mặc định là 4 và độ ưu tiên này có thể thay đổi từ -20 tới +20 + để giảm độ ưu tiên đi:

% nice +12 a.out + để tăng độ ưu tiên lên:

% nice -15 a.out

h. Hiển thị trạng thái các tiến trình

Lệnh ps cho phép hiển thị trạng thái của mọi tiến trình đang chạy tại một thời điểm như sau:

% ps<RETURN>

PID TT STAT TIME COMMAND 2234 p0 S 0:00 -csh (csh) 2276 p0 R 3:05 exe

2288 p0 R 1:32 a.out 2291 p0 R 0:00 ps

j. Cấu trúc cây của tiến trình

Tập hợp các tiến trình trong hoạt động của hệ điều hành UNIX thể hiện một cấu trúc hình cây.

Từ đỉnh của cấu trúc cây, ở một mức tương đương với mức của gốc (root) trong hệ thống các tệp của UNIX, có một tiến trình chủ, vượt lên trên mọi tiến trình hiện có.

Tiến trình này ở mức cao nhất được gọi là init (khởi đầu) và nó được tạo ra bởi "lõi" hệ điều hành, tại thời điểm nạp của hệ thống. Tới lượt nó, init lại có vai trò tạo ra một tiến trình khi người sử dụng được nối kết. Đó là tiến trình được gọi trước tiến trình cha của phiên làm việc và được gán cho mỗi người sử dụng. Tiến trình cha là một Shell như ta đã thấy, sẽ tạo ra các tiến trình con dưới sự tác động của người sử dụng được nối kết.

Tiến trình init cũng tạo ra các tiến trình hệ thống mà ta gọi là các daemon. Các daemon nói chung là ở trạng thái chờ trong phần lớn thời gian. Chúng sẽ được gọi đến theo trình tự (lịch) của hệ thống để tiến hành các nhiệm vụ chính xác, ví dụ như thiết lập các tệp thiết bị ngoại vi.

Khi một tiến trình được tạo ra, nó được cung cấp một cách tự động một môi trường như của tiến trình cha, với số của tiến trình (pid) và thời gian thực hiện. Nếu có yêu cầu trong lệnh một sự hiệu chỉnh độ ưu tiên, độ ưu tiên mới sẽ được lưu ý trong môi trường của tiến trình con. Khái niệm về Shell con, hoặc nói chung là về tiến trình con, được sử dùng nhiều trong các tệp lệnh.

Chú ý:

Tuỳ chọn -l của lệnh ps cho phép xây dựng lại cấu trúc hình cây của các tiến trình.

k. Làm sao biết một tiến trình hậu trường kết thúc?

1- B ng l nh psằ

Bằng lệnh ps ta hiển thị bảng trạng thái các tiến trình, qua đó có thể biết tiến trình hậu trường của ta kết thúc hay chưa.

2- B ng l nh notifyằ

Bằng lệnh notify (một lệnh nội trú của C Shell) ta sẽ tương tác với máy và biết được sự thay đổi trạng thái của một "job".

l. Các tài nguyên của một tiến trình

Lệnh limit của C Shell, không có đối số, cho phép có được thông tin về các tài nguyên tối đa của một tiến trình:

% limit<RETURN> ví dụ ta nhận được các thông tin sau:

cputime unlimited filesize unlimited datasize 524280 kb stacksize 8192 kb coredumpsize unlimited memoryuse unlimited

Nếu kích hoạt lệnh limit với một đối số phù hợp, mỗi tài nguyên tương ứng có thể được bổ sung như sau:

Ví dụ 1: ta cố định thời gian là 300 giây (tức 5 phút) cho cputime % limit cputime 300 (adsbygoogle = window.adsbygoogle || []).push({});

Ví dụ 2: ta cố định kích cỡ bộ nhớ có thể dùng được là 500 kb % limit memoryuse 500 kb Ta nhận được các thông tin mới:

%limit cputime 5:00 filesize unlimited datasize 524280 kb stacksize 8192 kb coredumpsize unlimited memoryuse 500 kb

Lệnh unlimit cho phép hủy những tác động do lệnh limit sinh ra và trở lại những hạn chế theo giá trị mặc định trước đó:

% unlimit<RETURN>

Một phần của tài liệu Giáo trình sử dụng quản trị và lập trình UNIX LINUX (Trang 43 - 48)