Bài giảng Nguyên lý Hệ điều hành - Chương 3: Tiến trình - Phạm Quang Dũng

3.1. Looking at Processes  Tiến trình (Process): là chương trình đang được chạy.  Vd:  có 2 terminal window -> 2 tiến trình  mỗi terminal window chạy 1 shell -> mỗi shell là một tiến trình  gõ lệnh trong shell -> chương trình tương ứng được thực hiện trong 1 tiến trình mới. Lập trình viên chuyên nghiệp thường sử dụng nhiều luồng hợp tác trong cùng một ứng dụng:  ứng dụng thực hiện được nhiều việc hơn  tăng tính mạnh mẽ của ứng dụng  tăng tính hữu dụng của các chương trình đã tồn tạ

pdf22 trang | Chia sẻ: candy98 | Lượt xem: 599 | Lượt tải: 0download
Bạn đang xem trước 20 trang tài liệu Bài giảng Nguyên lý Hệ điều hành - Chương 3: Tiến trình - Phạm Quang Dũng, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
Tiến trình 23.1. Looking at Processes  Tiến trình (Process): là chương trình đang được chạy.  Vd:  có 2 terminal window -> 2 tiến trình  mỗi terminal window chạy 1 shell -> mỗi shell là một tiến trình  gõ lệnh trong shell -> chương trình tương ứng được thực hiện trong 1 tiến trình mới. 3 Lập trình viên chuyên nghiệp thường sử dụng nhiều luồng hợp tác trong cùng một ứng dụng:  ứng dụng thực hiện được nhiều việc hơn  tăng tính mạnh mẽ của ứng dụng  tăng tính hữu dụng của các chương trình đã tồn tại 4Process IDs  Mỗi tiến trình trong HĐH Linux có Process ID duy nhất (pid)  pid là số 16-bit được Linux gán tuần tự khi một tiến trình mới được tạo.  Mỗi tiến trình có một parent process, ngoại trừ tiến trình init.  C, C++:  sử dụng định nghĩa kiểu pid_t  Các system call: getpid(), getppid() 5 6Viewing active processes  Lệnh shell: ps  Hiển thị các tiến trình đang chạy trên hệ thống  Hiển thị tất cả các tiến trình (-e) 73.2. Creating Processes  Dùng system  Tuy nhiên, vì hàm system sử dụng shell để thực hiện lệnh nên kết quả phụ thuộc loại shell và quyền của user. 8Dùng fork và exec  Để tạo một tiến trình mới:  đầu tiên sử dụng fork để tạo bản sao (tiến trình con) của tiến trình hiện tại  sau đó dùng exec để chuyển một trong hai tiến trình thành một cá thể của chương trình muốn tạo 9Gọi fork  Tiến trình cha tiếp tục thực hiện chương trình tại điểm mà fork được gọi  Tiến trình con cũng thực hiện chương trình tương tự từ điểm đó.  Giá trị trả về của tiến trình cha là PID của tiến trình con  Giá trị trả về của tiến trình con là 0.  Vd: Listing 3.3: fork.c 10 Sử dụng exec family  Khi một chương trình gọi exec, tiến trình đó lập tức dừng việc thực hiện và bắt đầu thực hiện một chương trình mới từ đầu.  Hàm trong tên có chữ p (execvp, execlp): chấp nhận tên 1 chương trình và tìm CT trong đường dẫn hiện tại  Hàm trong tên có chữ v (execv, execvp, execve): chấp nhận danh sách tham số cho chương trình mới như một NULL-terminated array của các con trỏ tới các chuỗi ký tự. Hàm trong tên có chữ l (execl, execlp, execle) chấp nhận danh sách tham số sử dụng cơ chế tham biến của C.  Hàm trong tên có chữ e (execve, execle): chấp nhận một tham số thêm, một mảng của các biến môi trường 11 Ví dụ sử dụng fork và exec  Listing 3.4: fork-exec.c 12 3.3. Signals  Signals: cơ chế để giao tiếp và thao tác với các tiến trình trong Linux  Chủ đề signals rất rộng, ở đây ta chỉ xét một số signals quan trọng nhất và các kỹ thuật được sử dụng để điều khiển tiến trình.  Một signal là một message đặc biệt được gửi tới một tiến trình.  Signals là không đồng bộ: khi 1 tiến trình nhận 1 signal, nó lập tức xử lý signal mà không cần đợi kết thúc hàm hiện tại hoặc thậm chí chưa kết thúc dòng lệnh hiện tại. 13 Các cách gửi signal đến tiến trình  HĐH Linux có thể gửi các signals tới một tiến trình đang cố gắng thực hiện một hành động không hợp lệ  Vd: SIGBUS (bus error), SIGSEGV (segmentation violation), SIGFPE (floating point exception)  Xử lý mặc định là kết thúc tiến trình, tạo 1 core file.  Tiến trình này cũng có thể gửi signal tới tiến trình khác:  Kết thúc tiến trình khác: SIGTERM, SIGKILL  Gửi 1 lệnh tới 1 chương trình đang chạy: SIGUSR1, SIGUSR2 14 Hàm sigaction  được dùng để thiết lập cách xử lý một signal.  tham số thứ nhất: signal number  tham số thứ hai: cách xử lý mong muốn  tham số thứ ba: nhận cách xử lý trước đó  Trường quan trọng nhất trong cấu trúc sigaction thứ nhất hoặc thứ hai là sa_handler, có thể nhận 1 trong 3 giá trị:  SIG_DFL: xác định cách xử lý mặc định cho signal  SIG_IGN: xác định là signal nên bị bỏ qua  Con trỏ tới một hàm signal-handler, hàm nên có 1 tham số là signal number và kiểu trả về là void. 15 .  Vì các signal là không đồng bộ, chương trình chính ở trạng thái “mong manh” khi signal được xử lý.  Vì vậy nên tránh thực hiện vào/ra hoặc gọi các hàm thư viện, hàm hệ thống trong các signal handler.  Signal handler nên thực hiện công việc cần thiết tối thiểu rồi trả điều khiển về cho chương trình chính. 16  Việc gán giá trị cho một biến toàn cục có thể nguy hiểm vì thực tế phép gán có thể được thực hiện trong 2 hay nhiều lệnh máy. Nếu một signal xuất hiện xen giữa thì biến bị rơi vào trạng thái bị phá vỡ.  Nên dùng kiểu đặc biệt sig_atomic_t (kiểu int) khi sử dụng biến toàn cục để lập cờ cho signal trong một hàm signal-handler. Linux đảm bảo phép gán giá trị cho các biến kiểu này được thực hiện chỉ trong 1 lệnh. 17 Ví dụ  Sử dụng 1 hàm signal handler để đếm số lần chương trình nhận được SIGUSR1.  Listing 3.5: sigusr1.c 18 3.4. Process Termination  Bình thường thì tiến trình có thể chấm dứt khi:  chương trình đang thực hiện gọi hàm exit  hàm main của chương trình trả về giá trị  Mỗi tiến trình có một exit code – số mà tiến trình trả về cho cha nó.  Tiến trình có thể bị dừng bất thường khi nhận được 1 signal như SIGBUS, SIGSEGV, SIGFPE, SIGINT, SIGTERM  Tiến trình tự gửi signal SIGABRT cho chính nó qua hàm abort để chấm dứt tiến trình  signal mạnh nhất SIGKILL: lập tức dừng tiến trình 19  Lệnh shell: % kill –KILL pid  Lệnh C:  kill(child_pid,SIGTERM);  (dùng các header sys/types.h và signal.h) 20 3.4.1. Đợi chấm dứt tiến trình  Tiến trình cha và tiến trình con được lập lịch độc lập với nhau.  Linux là HĐH đa nhiệm, các tiến trình có thể được thực hiện cùng nhau, ta ko thể đoán trước được tiến trình con sẽ được chạy trước hay sau tiến trình cha.  Trong một số trường hợp, có thể dùng các system call wait family để cho phép tiến trình cha đợi tiến trình con kết thúc và nhận thông tin kết thúc đó. 21 3.4.2. Các system call wait  wait:  khóa tiến trình, gọi nó đến khi một trong các tiến trình con của nó thoát (hoặc khi 1 lỗi xuất hiện).  mã trạng thái thoát trả về là 1 số nguyên. Dùng macro WIFEXITED để xác định trạng thái này:  =True: thoát bình thường  =False: thoát không bình thường (chết vì tín hiệu không được xử lý.  Vd: code trang 81 22 Các system call wait(tiếp)  waitpid:  Đợi kết thúc của 1 tiến trình con cụ thể.  wait3:  Trả về thống kê sử dụng CPU của tiến trình con đang tồn tại.  wait4:  Cho phép xác định các lựa chọn thêm về cần đợi các tiến trình nào.