Tải bản đầy đủ (.docx) (26 trang)

Nhom2 quan li tien trinh trong HDH linux

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (528.05 KB, 26 trang )

BỘ CÔNG THƯƠNG
TRƯỜNG ĐẠI HỌC CÔNG NGHIỆP HÀ NỘI
KHOA CÔNG NGHỆ THÔNG TIN
----  ----

BÀI TẬP LỚN
Giáo viên: Th.s Nguyễn Tuấn Tú

MÔN NGUYÊN LÝ HỆ ĐIỀU HÀNH
NHÓM 2
LỚP ĐH KHMT 3-K9

TRƯỜNG ĐẠI HỌC CÔNG NGHIỆP HÀ NỘI
KHOA CÔNG NGHỆ THÔNG TIN


------ ------

BÁO CÁO BÀI TẬP LỚN
MÔN HỌC
NGUYÊN LÝ HỆ ĐIỀU HÀNH
Đề tài: Quản lý tiến trình trong hệ điều hành Linux
Giáo viên hướng dẫn: ThS Nguyễn Tuấn Tú
Lớp: ĐH KHMT3-K9
STT

Sinh viên thực hiện

Mã SV

1



Trần Văn Trịnh

0941060223

2

Hoàng Văn Tiến

0941060253

3

Trần Thị Mai Hương

0941060252

4

Nguyễn Tiến Dũng

0941060212

5

Nguyễn Việt Phương

0941060197



MỤC LỤC


Lời mở đầu

Vài năm qua, Linux đã thực sự tạo ra một cuộc cách mạng trong lĩnh vực máy tính.
Sự phát triển và những gì chúng mang lại cho máy tính thật đáng kinh ngạc: một hệ
điều hành đa nhiệm, đa người dùng. Linux có thể chạy trên nhiều bộ vi xử lý khác
nhau như: Intel , Motorola , MC68K , Dec Alpha. Nó tương tác tốt với các hệ điều
hành: Apple , Microsoft và Novell. Không phải ngẫu nhiên mà ngành công nghệ
thông tin Việt Nam chọn Linux làm hệ điều hành nền cho các chương trình ứng dụng
chủ đạo về kinh tế và quốc phòng. Với mã nguồn mở, sử dụng Linux an toàn hơn các
ứng dụng Windows. Linux đem đến cho chúng ta lợi ích về kinh tế với rất nhiều phần
mềm miễn phí. Mã nguồn mở của hệ điều hành và của các chương trình trên Linux là
tài liệu vô giá để chúng ta học hỏi về kỹ thuật lập trình vốn là những tài liệu không
được công bố đối với các ứng dụng Windows. Trong đồ án này, chúng ta sẽ tìm hiểu
một phần rất quan trọng trong hệ điều hành Linux đó là: quản lý bộ nhớ trong Linux.
Một hệ điều hành muốn chạy ổn định thì phải có một cơ chế quản lý bộ nhớ hiệu quả.
Cơ chế này sẽ được trình bày một cách chi tiết trong đồ án và có kèm theo các
chương trình minh họa

4


1. Giới thiệu về hệ điều hành linux.
1.1Tổng quan về hệ điều hành.

Phần mềm máy tính chia ra làm hai loại: đó là các phần mềm hệ thống, quản
lí hoạt động của bản thân máy tính, và các chương trình ứng dụng, giải quyết các
yêu cầu của người dùng.

Phần căn bản nhất của tất cả các phần mềm hệ thống gọi là Hệ điều hành.
Hệ điều hành là một phần mềm chạy trên máy tính, dùng để điều hành, quản lí
các thiết bị phần cứng và các tài nguyên phần mềm trên máy tính.
Hệ điều hành đóng vai trò trung gian giao tiếp giữa người sử dụng với phần
cứng máy tính, cung cấp một môi trường cho người sử dụng và phát triển các ứng
dụng của họ một cách dễ dàng.
Hệ điều hành là một phần quan trọng của hầu hết các hệ thống máy tính. Hệ
điều hành chạy trong môi trường đặc biệt, gọi là chế độ nhân (Kernel mode hay
Supervisor mode). Chế độ chạy này được hỗ trợ biển kiến trúc của CPU( bởi các
lệnh máy đặc biệt) và nó ngăn người dùng truy cập vào phần cứng ( quản lí phần
cứng chuẩn xác cho nhiều người dùng đồng thời, còn gọi là chế độ được bảo vệ
(protect mode)).
Chức năng chủ yếu của hệ điều hành đó là: Quản lí chia sẻ tài nguyên (CPU,
bộ nhớ trong, bộ nhớ ngoài…) và Giả lập một máy tính mở rộng.
Ngoài ra còn có thể chia chức năng của hệ điều hành theo bốn chức năng là:
+ Quản lí quá trình (Proccess manament)
+ Quản lí bộ nhớ (Memory manament)
+ Quản lí hệ thống lưu trữ
+ Giao tiếp với người dùng (User interaction).
Nhiệm vụ của hệ điều hành:
+ Điều khiển quản lí trực tiếp các phần cứng như bo mạch chủ, bo mạch đồ
họa và bo mạch âm thanh….
+ Thực hiện một số thao tác cơ bản trong máy tính như các thao tác đọc , viết
tập tin, quản lí hệ thống tập tin (file system) và các kho dữ liệu.

+ Cung ứng một hệ thống giao diện sơ khai cho các ứng dụng thường là thông qua
5


một hệ thống thư viện hàm chuẩn để hệ diều hành các phần cứng mà từ đó các ứng

dụng có thể gọi tới.
+ Cung ứng một hệ thống lệnh cơ bản để điều hành máy. Các lệnh này gọi là
lệnh hệ thống ( system command).
+ Ngoài ra hệ điều hành, trong vài trường hợp, cũng cung cấp các dịch vụ cơ
bản cho các phần mềm ứng dụng thông thường như chương trình duyệt web hay soạn
thảo văn bản….
Các thành phần của hệ điều hành bao gồm:
+ Hệ thống quản lí tiến trình.
+ Hệ thống quản lí bộ nhớ.
+ Hệ thống quản lí nhập xuất.
+ Hệ thống quản lí tập tin.
+ Hệ thống bảo vệ.
+ Hệ thống dịch lệnh.
+ Quản lí mạng.
1.2

Hệ điều hành linux.

- Linux là hệ điều hành mô phỏng Unix, được xây dựng trên phần nhân
(kernel) và các gói phần mềm mã nguồn mở. Linux được công bố dưới bản quyền của
GPL (General Public Licence).
- Linux cũng là một hệ điều hành cho nhiều nền máy tính khác nhau nhưng
trước tiên là cho PC nền Intel. Đó là hệ điều hành có hàng trăm nhà lập trình tham
gia thiết kế và xây dựng, với mục tiêu là tạo ra một bản giống UNIX hoàn toàn không
lệ thuộc vào phần mềm có đăng kí tác quyền nào và cả thế giới có thể sử dụng thoải
mái.
- Thành phần cơ bản của Linux là hạt nhân Linux ( thường được gọi là nhân
Linux-Linux kernel), là nhân hệ điều hành được phát triển bởi Linus Torvalds được
công bố lần đầu tiên vào 9/1991 với phiên bản 0.0.1.
- Ngày 5/4/1991, Linus Torvalds, chàng sinh viên trường Đại học Helsinki,

Phần Lan đã bắt tay vào viết những dòng lệnh đầu tiên của Linux.

6


Hình 1.1:Torvalds – Người “cha đẻ” của Linux Linus

Tháng 9/1991 phiên bản Linux 0.0.1 , phiên bản đầu tiên được Torvalds công
bố với 10239 dòng lệnh. Phiên bản 0.0.2 cũng được công bố 1 tháng sau đó.
Năm 1992, Torvalds cho phát hành Linux dưới dạng mã nguồn mở của giấy
phép GPL, cho phép mọi người có thể download về để xem mã nguồn mở để cùng
chung tay phát triển.
Năm 1993, Slackware, hệ điều hành đầu tiên được phát triển dựa trên mã
nguồn mở Linux đã ra đời. Phiên bản mới nhất của Slackware được phát hành
5/2010 . 14/3/1994 Sau 3 năm làm việc, Torvalds đã cho ra mắt phiên bản hoàn thiện
đầu tiên, Linux 1.0 ra đời với 176.250 dòng lệnh. Sau đó 1 năm, phiên bản 1.2 ra đời
với 310.950 dòng lệnh.
Ngày 3/11/1994 Red Hat Linux, phiên bản 1.0 được giới thiệu. Đây là một
trong những phiên bản được thương mại hóa đầu tiên dựa trên Linux.
Năm 1996, hình ảnh chú chim cánh cụt được lấy làm biểu tượng của Linux.
Năm 1998, Linux được IBM, Compaq, Oracle..quan tâm đầu tư phát triển….
Năm 2007, các hãng máy tính HP, ASUS., Dell… cũng bắt đầu bán ra các sản
phẩm laptop được cài sẵn Linux.
1/2009, số người dùng Linux đạt tới con số 10 triệu người.
Hiện nay sau 20 năm tồn tại phát triển, Linux đã được đông đảo mọi người
biết đến và sử dụng, vốn chỉ từ hệ điều hành hơn 10 ngàn câu lệnh, phiên bản mới
nhất 2.6.38 đã được phát hành với 14.294.493 dòng lệnh đánh dấu chặng đường tồn
tại và phát triển của Linux.

7



2.

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

- Tiến trình là một chương trình đang xử lí, nó sở hữu một con trỏ lệnh, tập các
thanh ghi và các biến. Để hoàn thành nhiệm vụ của mình, các tiến trình có thể con
yêu cầu một số tài nguyên hệ thống như CPU, bộ nhớ chính và các tập tin và các
thiết bị nhập/xuất.
- Để hỗ trợ hoạt động đa nhiệm, hệ thống máy tính cần phải có khả năng thực hiện
nhiều tác vụ xử lí đồng thời những việc điều khiển hoạt động song hành ở cấp độ
phần cứng là rất khó khăn. Vì vậy các nhà thiết kế hệ điều hành đề xuất một mô hình
song hành giả lập bằng cách chuyển đổi bộ xử lí qua lại giữa các chương trình để
duy trì hoạt động của nhiều chương trình tại cùng một thời điểm. trong mô hình này,
các chương trình trong hệ thống được tổ chức thành các tiến trình (process).
Tiến trình (process) là trạng thái tức thời của một chương trình đang chạy trên máy
tính. Nó bao gồm bộ nhớ cần thiết để chạy chương trình (không gian địa chỉ của Tiến
trình) và khả năng kiểm soát hiện trạng của bộ xử lý trong Tiến trình thực thi chương
trình (tiến trình điều khiển của Tiến trình). Luồng (thread) tương tự như Tiến trình
nhưng chỉ bao gồm tiến trình điều khiển. Nhiều luồng sử dụng không gian địa chỉ
của một Tiến trình
-Có 3 loại tiến trình:
+ Tiến trình có tương tác (Interactive processes) : là tiến trình khởi động và quản lý
bởi shell, kể cả tiến trình forthground hoặc background.
+ Tiến trình batch (Batch processes) : Tiến trình không gắn liền đến terminal và
được nằm trong hàng đợi để lần lượt thực hiện.
+ Tiến trình ẩn trên bộ nhớ (Daemon processes) : Là các tiến trình chạy dưới nền
(background). Các tiến trình này thường được khởi động từ đầu. Đa số các chương
trình

3.

Các trạng thái của một tiến trình.

8


Hình 3.1:các bước của 1 tiến trình
Trong môi trường hệ điều hành Linux, một tiến trình có các trạng thái sau:
+ Runnable: tiến trình ở trạng thái sẵn sàng để chạy. Nó đã được cấp phát đầy
đủ các tài nguyên và chỉ đợi tới phiên được cấp CPU thì sẽ chạy.
+ Sleeping: tiến trình đang đợi một sự kiện nào đó xảy ra, khi sự kiện đó xảy
ra nó sẽ được duyệt chờ cấp phát CPU để chạy. Ví dụ: một tiến trình đang đợi một
thao tác đọc/ghi file nào đó hoàn tất hoặc một tiến trình dịch vụ mạng đang đợi có
yêu cầu từ phía client đều là các tiến trình sleeping. Trong trường hợp đặc biệt, có
một số tiến trình rơi vào tình trạng không thể đánh thức nó bằng một sự kiện nào
được. Những tiến trình này được kí hiệu là D (uninterruptible process).
+ Zoombie: tiến trình đã kết thúc nhưng nó không được xóa sạch sẽ khỏi RAM
và tiến trình cha của của nó không nhận được thông báo về việc nó đã kết thúc. Nhìn
chung các tiến trình zoombie không gây hại gì. Nếu muốn dọn dẹp các tiến trình này,
cách duy nhất là khởi động lại máy.
+ Traced/Stopped: Những tiến trình đã bị buộc dừng lại. Tiến trình rơi vào
trạng thái này do nhận được signal STOP hoặc TSTP và chỉ có thể chạy lại khi nhận
được signal CONT hoặc khi người dùng cho nó chạy trong chế độ background/
foreground bằng lệnh bg/fg.
- Running(đang chạy): Tiến trình chiếm quyền xử lí CPU dùng tính toán hay thực thi
các công việc của mình.
- Waiting(chờ): Tiến trình bị HĐH tước quyền xử lí CPU và chờ đến lượt cấp phát
khác.
- Suspend(tạm dừng): HĐH tạm dừng tiến trình, tiến trình được đưa vào trạng thái

ngủ ( sleep), khi cần thiết và có nhu cầu HĐH sẽ đánh thức(wake up) hay nạp lại mã
9


lệnh của tiến trình vào bộ nhớ, cấp phát tài nguyên CPU để tiến trình tiến trình có
thể hoạt động.
Nếu một tiến trình đang chạy ở tiền cảnh và bạn muốn đưa chúng vào hậu cảnh, bạn
thực hiện công việc này bằng cách nhấn tổ hợp phím Ctrl + Z. Khi nhận được tín
hiệu Ctrl+Z tiến trình sẽ b ị t ạm dừng và được đưa vào hậu cảnh. Tuy nhiên bạn
chưa biết được chương trình của chúng ta đã dừng chưa và đã chuyển vào hậu cảnh
chưa. Lệnh jobs hiển thị trạng thái của tất cả các tiến trình đang chạy ở hậu cảnh:
- Hàm fork() để nhân bản một tiến trình
- Hàm system() để tạo lập tiến trình mới
- Hàm exec() dùng để thay thế tiến trình hiện hành

4.

Quan hệ giữa các tiến trình.

Các tiến trình hoạt động trong hệ thống tồn tại 2 mối quan hệ: độc lập và hợp
tác(song hành.
* Quan hệ độc lập: tiến trình được gọi là độc lập nếu hoạt động của nó không
gây ảnh hưởng hoặc không bị ảnh hưởng của các tiến trình khác cũng đang hoạt
động của hệ thống.
Tiến trình độc lập có những đặc trưng sau:
- Trạng thái của nó không bị chia sẻ với bất kì tiến trình nào khác.
- Việc thực hiện tiến trình là đơn định(kết quả chỉ phụ thuộc vào đầu vào).
- Tiến trình có thể tái hiện(lặp lại).
- Tiến trình có thể dừng hoặc bắt đầu lại mà không gây ảnh hưởng tới các tiến
trình khác trong hệ thống.

* Quan hệ hợp tác: Tiến trình được gọi là hợp tác(song hành) nếu hoạt động
của nó gây ảnh hưởng hoặc bị ảnh hưởng bởi các tiến trình khác cũng đang hoạt
động trong hệ thống.
Tiến trình hợp tác có những đặp trưng sau:
- Trạng thái của nó bị chia sẻ cho các tiến trình khác.
10


- Việc thực hiện tién trình là không đơn định(kết quả phụ thuộc dãy thực
hiện tương ứng và không dự báo trước).
- Tiến trình không thể tái hiện.

5.

Quản lý tiến trình trên linux.

5.1. Tại sao phải quản lý tiến trình.
* Nhiệm vụ của quản lý tiến trình :
- Tạo lập, hủy bỏ tiến trình.
- Tạm dừng, tái kích hoạt tiến trình.
- Tạo cơ chế thông tin liên lạc giữa các tiến trình .
- Tạo cơ chế đồng bộ hóa giữa các tiến trình.
* Mục tiêu :
- Hạn chế tối đa xung đột và bế tắc xảy ra, đưa ra giải pháp nếu xảy ra các tình
huống đó
- Tận dụng tối đa khả năng của CPU (bài toán lập lịch).
Tiến trình là một môi trường thực hiện, bao gồm một phân đoạn lệnh và
một phân đoạn dữ liệu. Cần phân biệt với khái niệm chương trình chỉ gồm tập
hợp lệnh.
Trên hệ điều hành Linux, tiến trình được nhận biết thông qua số hiệu của

tiến trình, gọi là pid. Cũng như đối với user, nó có thể nằm trong nhóm. Vì thế
để phân biệt ta nhận biết qua số hiệu nhóm gọi là PRGP. Một số hàm của C
cho phép lấy được những thông số này:
int getpid() : trả về giá trị int là pid của tiến trình hiện tại
int getppid() : trả về giá trị int là pid của tiến trình cha của tiến trình hiện tại
int getpgrp() : trả về giá trị int là số hiệu của nhóm tiến trình
int setpgrp() : trả về giá trị int là số hiệu nhóm tiến trình mới tạo ra
Ví dụ
Lệnh : printf("Toi la tien trinh %d thuoc nhom %d",getpid(),getgrp());
Kết quả sẽ là: Toi là tien trinh 235 thuoc nhom 231.
11


5.2.

Cấu trúc của một tiến trình.
Cách thúc quản lý của tiến trình của linux:
+Hai user niel và rick cùng đăng nhập và chạy chương trình grep đồng
thời HĐH lúc này sẽ quản lý và nạp mã truy cập chương trình grep vào hai
vùng nhớ khác nhau và gọi mỗi phân vùng như là 1 tiến trình.
Hình 5.1 người dùng neil chạy chương trình grep tìm chuỗi “abc” trong
tập tin trec.txt còn người dùng rick chạy chương trình grep tìm chuỗi
“cde”trong tập tin somefile.doc

Hình 5.1 tiến trình quản lý bởi HĐH

12


-Dùng lệnh ps cho phép xem thông tin về các tiến trình mà linux đang kiểm soát

(có thể sử dụng thêm tham số “-af “ để lieettj kê chi tiết thông tin về các tiến
trình):
-Mỗi tiến trình được gán cho định danh gọi là PID(Process Identifier)
-PID là một số nguyên dương có giá trị từ 2-32768
-Tiến trình init được gọi và chạy ngay khi ta khởi động HĐH.Đây là tiến trình
quản lý và tạo ra mọi tiến trình con khác Có PID là 1
-Cách thức gán PID :khi một tiến trình mới yêu cầu khởi động ,HĐH sẽ chọn
lấy một giá trị số nguyên khoảng 2-32768 (số nguyên naỳ chưa bị tiến trình đang
chạy nào chiếm giữ) và cấp phát cho tiến trình này. Khi tiến trình chấm dứt HĐH
sẽ thu lại số PID để cấp phát cho tiến trình khác trong lần sau.
-Trên Unix/Linux, thư mục /proc chứa các file lưu trữ thông tin về những tiến
trình đang chạy.
-Theo quy ước,mỗi tiến trình hoạt động không gian địa chỉ ảo độc lập do hệ
thống cấp phát 4Gb.
5.3.

5.4.

Tạo một tiến trình.
int fork() tạo ra một tiến trình con. Giá trị trả lại là 0 cho tiến trình con và
dấu hiệu pid cho tiến trình cha. Giá trị sẽ là -1 nếu không tạo được tiến trình
mới. Theo nguyên tắc cơ bản của hệ thống, tiến trình con và cha sẽ có cùng
đoạn mã. Đoạn dữ liệu của tiến trình mới là một bản sao chép chính xác đoạn
dữ liệu của tiến trình cha. Tuy nhiên tiến trình con vẫn khác tiến trình cha ở pid,
thời gian xử lý, ...
Giám sát và điều khiển các tiến trình.
Một program là một file thực thi trong hệ thống.

Ví dụ: /sbin/shutdown,/sbin/init.
Process là một instance của một program đang thực thi (ví dụ khi ta chạy

cùng lúc nhiều của sổ Word, mỗi cửa sổ là một instance của ứng dụng Word).
Process đôi khi còn được gọi là task.
Lấy thông tin trạng thái của các tiến trình: sử dụng câu lệnh ps, top
13


1.4.1

Lệnh PS.

+ Lệnh ps, thông số:
- e: hiển thị thông tin về mỗi tiến trình.
- l: hiển thị thông tin đầy đủ tiến trình.
- f: hiển thị thông tin về tiến trình cha.
- a: hiển thị tất cả các tiến trình.
- aux: liệt kê danh sách các tiến trình đang chạy cùng các thông tin của nó.

Hình 5.2
Mỗi tiến trình của Linux đều mang một số ID và các thao tác liên quan đến
tiến trình đều thông qua số PID này. Gạch nối – trước bash để thông báo đó là
shell khởi động khi người sử dụng login.
Để hiển thị tất cả các process, ta có thể sử dụng lệnh ps –a. Một người sử dụng hệ
thống bình thường có thể thấy tất cả các tiến trình, nhưng chỉ có thể điều khiển
được các tiến trình của mình tạo ra. Chỉ có superuser mới có quyền điều khiển tất
cả các tiến trình của hệ thống Linux và của người khác. Lệnh ps –aux cho phép
hiển thị tất cả các tiến trình, ngay cả những tiến trình không gắn liền đến có bàn
điều khiển (tty). Chúng ta có thể coi các tiến trình đang chạy cùng với dòng lệnh
đầy đủ để khởi động tiến trình này bằng ps –aux
14



1. Chủ nhân của tiến trình (owner)
2. Mã số nhận diện tiến trình (PID)
3. Mức sử dụng CPU (%CPU)
4. Mức chiếm dụng bộ nhớ của tiến trình (%MEM)
5. VSZ - lượng bộ nhớ ảo (phần đĩa cứng giả làm RAM) mà tiến trình sử
dụng, tính theo byte
6. RSS - lượng bộ nhớ RAM mà tiến trình sử dụng, tính theo byte
7. TTY - terminal mà tiến trình được khởi tạo trên đó. Dấu hỏi ? thể hiện
tiến trình này là một daemon và nó không liên kết với một terminal nào?
8. trạng thái tiến trình (STAT)
9. thời điểm khởi chạy (START)
10.thời gian đã chạy (TIME) và các thông tin khác.
5.4.2 Lệnh Top.
Giống lệnh ps nhưng danh sách các process được update liên tục. Các
thông số về CPU, RAM cũng được thể hiện và Update. Tham sô –d (delay: khoảng
thời gian refresh giữa 2 lần), -n (number: chạy n lần và ngưng)

15


Hình 5.3

5.5.

Dừng một tiến trình.
Lệnh kill của Shell có thể dùng để chấm dứt hoạt động của một tiến trình.
+ Lệnh kill:
# kill <signal | number> Gởi tín hiệu cho một tiến trình đang
chạy

+ Lệnh kill:
# kill <signal | number>
16


Hình 5.4: Ý nghĩa 1 số lệnh
Lệnh kill có thể gởi bất kỳ tín hiệu signal nào tới một tiến trình, nhưng theo
mặc định nó gởi tín hiệu 15, TERM (là tín hiệu kết thúc chương trình).
Lệnh kill -9 PID: ngừng thi hành tiến trình mà không bị các tiến trình khác can
thiệp (tín hiệu 9, KILL).
Super-user mới có quyền dừng tất cả các tiến trình, còn người sử dụng chỉ được
dừng các tiến trình của mình.
Các signal thường dùng lệnh kill bao gồm:
Tên Giá trị Tác động
- SIGHUP 1 - Hangup (gọi lại tiến trình)
- SIGINT 2 - Ngắt từ bàn phím (Ctrl+C)
- SIGKILL 9 - Hủy tiến trình
- SIGTERM 15 - Kết thúc tiến trình
- SIGSTOP 17,19,23: - Dừng tiến trình.
Khi kết thúc một tiến trình hay một chuỗi các tiến trình, thông thường nên tiến
hành thử với tín hiệu ít gây nguy hiểm nhất, SIGTERM, nếu không được mới sử
dụng các tín hiệu INT hay KILL.
Ví dụ như khi muốn dừng tiến trình 234 ta dùng lệnh: kill 234 C cũng có lệnh
kill như sau:
int kill(pid, sig);
int pid; là dấu hiệu nhận biết của một tiến trình.
int sig; hằng tín hiệu giao tiếp tiến trình
17



5.6. Chạy tiến trình ở trạng thái foreground và trạng thái background.
Quá trình chạy ở chế đọ hiện sẽ tiến hành theo các bước sau:
1

Thực hiện quá trình <<fock>>, nhân bản tiến trình cha (trong trường hợp
thực thi các lệnh,đó sẽ là tiến trình shell).

2

Thực hiện quá trình <<wait>>, đưa tiến trình cha vào trạng thái ngủ (sleep).

3

Thực hiện quá trình <<exec>>, thực thi tiến trình con. Sau khi tiến trình con
thực thi xong, một tín hiệu <<đánh thức>> sẽ được gửi tới tiến trình cha.

4

Do quá trình chạy như trên =>trong quá trình thực hiện tiến trình con, người
sử dụng không thể tương tác với tiến trình cha

5

Quá trình chạy ở chế độ ngầm cho phép thực thi tiến trình cha và tiến trình
con một cách độc lập.
Ví dụ: $ emacs&.

Sau khi thực hiện lệnh trên,emacs sẽ chạy ở chế đọ ngầm, người sử dụng có thể tiếp
tục sử dụng console để thực thi các lệnh khác.


5.7. Độ ưu tiên của các tiến trình (Priority).

Sử dụng lệnh nice, renice
+ Tất cả các tiến trình đều có độ ưu tiên ban đầu được ngầm định là 0.
+ Mức độ ưu tiên của một tiến trình dao động trong khoảng từ -19 đến +19.
Chỉ người sử dụng có quyền rút mới có thể giảm giá trị biểu diễn độ ưu tiên của tiến
trình. Một người sử dụng thông thường chỉ có thể làm giảm độ ưu tiên của tiến trình
thông qua việc tăng giá trị biểu diễn độ ưu tiên.
Sử dụng lệnh nice, renice để thay đổi độ ưu tiên.
+ Nice: cho phép thay đổi độ ưu tiên của một tiến trình ngay khi bắt đầu thực hiện
tương ứng với tiến trình
# nice [–n number] [command]
18


Ví dụ: # nice –n -10 vi /root/data.txt
+ Renice: cho phép thay đổi độ ưu tiên của một tiến trình sau khi đã chạy.
# renice priority PID [[- group] [[-u] user]
Ví dụ: # renice -2 203 Set nice number is -2 to PID=203
Can thiệp vào hoạt động
&: Cho một job hoạt động ở background
Ví dụ: # ls –l –R / > /root/list.txt & Ứng dụng ls sẽ chạy nền bên dưới
6

Giao tiếp giữa các tiến trình.
Việc giao tiếp giữa các tiến trình được thực hiện thông qua các tín hiệu chuẩn
của hệ thống. Tín hiệu là một sự ngắt quãng logic được gửi đến các tiến trình bởi
hệ thống để thông báo cho chúng về những sự việc không bình thường trong môi
trường hoạt động của chúng (như lỗi bộ nhớ, lỗi vào ra). Nó cũng cho phép các
tiến trình liên lạc với nhau. Một tín hiệu (trừ SIGKILL) có thể được xem xét theo

ba cách khác nhau:
Tiến trình có thể được bỏ qua: Ví dụ chương trình có thể bỏ qua sự ngắt quãng
của người sử dụng hệ thống (đó là sự bỏ qua khi một tiến trình đang được sử
dụng ở phần nền.
Tiến trình có thể được thực hiện: Trong trường hợp này, khi nhận được 1 tín
hiệu, việc thực hiện 1 tiến trình được chuyển về một quy trình do người sử dụng
xác định trước, sau đó trở lại nơi nó bị ngắt.
Lỗi có thể được tiến trình trả về sau khi nhận được tín hiệu này.Dưới đây là
một số tín hiệu thường gặp:
SIGHUP Tín hiệu này được phát đến các tiến trình vào lúc cuối khi mà nó tự
ngắt.Nó cũng được phát đến mọi tiến trình có tiến trình chính tự ngắt.
SIGINT Tín hiệu này được phát đến các tiến trình khi ta ra lệnh ngắt.
SIGQUIT Tương tự như trên khi ta gõ vào ^D.
SIGILL Lệnh không hợp lệ, tín hiệu được phát ra khi phát hiện 1 lệnh không
đúng
19


ở cấp độ vật lý (ví dụ như 1 tiến trình thực hiện một lệnh mà máy tính
chông có lệnh này).
SIGTRAP Tín hiệu được phát ra sau mỗi lệnh trong trường hợp tiến trình có
sử dụng lệnh ptrace().
SIGIOT Bẫy được phát khi có các vấn đề về vật lý.
SIGEMT Bẫy của lệnh phát, được phát ra khi có lỗi vật lý trong khi thực
hiện.
SIGFPE Được phát ra khi có lỗi về tính toán như một số có dấu phẩy nối có
định dạng không hợp lý. Gần như luôn chỉ ra lỗi khi lập trình.
SIGKILL Trang bị để kết thúc tiến trình. Không thể bỏ qua hoặc cắt tín hiệu
này.
SIGBUS Được phát khi gặp lỗi trên bus.

SYSGEGV Được phát ra khi gặp lỗi trên phân đoạn sự truy cập dữ liệu bên
ngoài phân đoạn dữ liệu được cấp phát cho tiến trình.
SIGSYS Đối số không đúng cho hệ thống gọi.
SIGPIPE Viết trên một ống dẫn không mở để đọc.
SIGALRM Phát ra khi đồng hồ của một tiến trình ngừng lại. Đồng hồ được
hoạt động bằng lệnh alrm().
SIGTERM Được phát ra khi một tiến trình kết thúc bình thường. Cũng có thể
dùng để dừng 1 hệ thống để kết thúc tất cả các tiến trình hoạt động.

7. Liên lạc giữa hai tiến trình.
Từ một chương trình đơn giản dưới đây sử dụng các lệnh phát và nhận tín
hiệu, sau đó giúp liên lạc giữa hai tiến trình.
Nội dung của ví dụ là sự liên lạc giữa một tiến trình cha và một tiến trình con
thông qua các tín hiệu đã được trình bày phần trước.
#include
#include
20


void fils_atc()
{
printf(" Tien trinh bi loai bo !!!\n");
kill(getpid(), SIGINT);
}
/***********************************/
void fils()
{
signal(SIGUSR1, fils_atc);
printf(" Hinh thanh tien trinh moi. Nhung chuan bi loai bo tien trinh
nay !!\n");

while(1);
}
/******************************/
main()
{
int ppid, pid;
if ((pid = fork())==0) fils();
else
{
sleep(3);
printf(" Chap nhan !! Tien trinh se bi loai bo.\n");
kill(pid, SIGUSR1);
}
}

21


Trong ví dụ trên, tiến trình con có sử dụng hàm signal(SIGUSR1, fils_atc).
Hàm này có tác dụng mỗi khi tiến trình con nhận được tín hiệu SIGUSR1 thì hàm
fils_atc() sẽ được thực thi.
Như vậy ở ví dụ trên một tiến trình con đã được tạo ra nhưng nó lại không
muốn tiếp tục tồn tại. Do vậy sau khi tạm dừng lại sleep(3), tiến trình cha đã gởi
đến cho tiến trình con một tín hiệu là SIGUSR1 bằng lệnh:
kill(pid, SIGUSR1);
Ở tiến trình con, tín hiệu SIGUSR1 đã được gán với hàm fils_atc(). Hàm này
ra một thông báo báo hiệu tiến trình này sắp chết rồi tự gởi đến chính mình (tiến
trình con) tín hiệu SIGINT, tín hiệu ngắt tiến trình. Và tiến trình con đã chết.
kill(getpid(), SIGINT);
Một số nhược điểm khi liên lạc trực tiếp bằng tín hiệu:

- Một tín hiệu có thể bị bỏ qua, kết thúc một tiến trình hoặc bị chặn lại. Đó là
lý do chính đưa ra các tín hiệu không thích ứng được để tiến hành liên lạc giữa
các tiến trình. Một thông điệp điệp dưới hình thức tín hiệu có thể sẽ bị mất nếu
nó được nhận lúc loại tín hiệu này tạm thời bị bỏ qua.
- Một vấn đề khác là các tín hiệu có quyền rất lớn, khi đến chúng làm
ngắt quãng công việc hiện tại. Ví dụ việc nhận một tín hiệu trong khi tiến trình
đang đợi một sự kiện (mà có thể đến khi sử dụng các lệnh open(), read(), ...) làm
cho việc thực thi hàm bị chệch hướng. Khi trở lại, lệnh chính bị ngắt gởi lại một
thông điệp báo lỗi mà hoàn toàn không xử lý được.
Ngoài việc liên lạc trực tiếp như ở ví dụ trên, còn cho phép một phương pháp
liên lạc giữa các tiến trình khác, đó là liên lạc qua "đường ống".

8. Lập lịch đa tiến trình.
8.1. Ống dẫn liên lạc
Ống dẫn là một cơ chế cơ bản để liên lạc gián tiếp giữa các tiến trình. Đó là
các file đặc biệt (FIFO), ở đó các thông tin được truyền đi 1 đầu và thoát ra ở một
đầu khác. Một số đặc điểm của "ống dẫn":
22


- Các ống dẫn chỉ mang tính chất tạm thời, chỉ tồn tại trong thời gian thực hiện
của một tiến trình tạo ra nó.
- Muốn tạo ra một ống dẫn phải bắt đầu bằng một lệnh đặc biệt: pipe().
- Nhiều tiến trình có thể viết và đọc trên cùng một ống dẫn. Tuy nhiên, không có
một cơ chế nào để phân biệt thông tin cho các tiến trình ở đầu ra.
- Dung lượng ống dẫn bị hạn chế (khoảng 4KB). Do đó khi chúng ta cố gắng viết
khi ống dẫn bị đầy thì sẽ gặp phải trường hợp tắc nghẽn.
- Các tiến trình liên lạc qua ống dẫn phải có mối quan hệ họ hàng và các ống dẫn
nối phải được mở trước khi tạo ra các tiến trình con.
- Không thể tự thay đổi vị trí thông tin trong ống.

8.2. Thao tác với ống dẫn liên lạc.
Tạo một ống dẫn:
int p_desc[2];
int pipe(p_desc);
Giá trị trả về là 0 nếu thành công, -1 nếu thất bại.
p_desc[0] : chứa các số hiệu mô tả nhờ đó có thể đọc trong ống dẫn.
p_desc[1] : chứa các số hiệu mô tả nhờ đó có thể viết trong ống dẫn.
Như vậy việc viết trong p_desc[1] là để truyền dữ liệu trong ống và việc đọc
trong p_desc[0] để nhận chúng.
Ví dụ:
#include
#include
main()
{
int i,ret, p_desc[2];
char c;
pipe(p_desc);
23


write(p_desc[1], "AB", 2);
for (i=1; i<=3,i ++) {
ret=read(p_desc[0], &c, 1);
if (ret == 1)
printf(" Gia tri: %c\n",c);
else
perror("Loi ong dan rong");
}
}
Ví dụ trên chỉ ra rằng ta có thể truyền và nhận thông tin trên ống dẫn.

Chúng ta đã dùng hàm read() và write() để viết (truyền) và đọc (nhận) trên
ống dẫn.

9. Liên lạc giữa tiến trình cha và tiến trình con.
Trong ví dụ dưới đây, một tiến trình tạo ra một ống dẫn, tạo ra một tiến trình
con, viết một văn bản vào ống dẫn.Tiến trình con thừa hưởng ống dẫn và các ký
hiệu mô tả của ống dẫn, thực hiện đọc trong ống dẫn:
#include
#include
void code_fils(int number) {
int fd, nread;
char texte[100];
- 31fd=number;
printf(" So hieu mo ta la %d\n",fd);
switch (nread=read(fd, texte, sizeof(texte)))
24


{
case -1:
perror("Loi doc.");
case 0:
perror("EOF");
default:
printf("Van ban nhan duoc co %d ky tu: %s\n",fd, texte);
}
}
main() {
int fd[2];
char chaine[10];

if (pipe(fd)==-1)
{ perror("Loi khoi tao pipe.");
exit(1);
}
switch (fork()) {
case -1:
perror(" Loi khoi tao tien trinh.");
break;
case 0:
if (close(fd[1])==-1)
perror(" Error.");
code_fils(fd[0]);
exit(0);
25


×