ĐẠI HỌC BÁCH KHOA HÀ NỘI TRƯỜNG ĐIỆN - ĐIỆN TỬ BÁO CÁO MÔN HỌC HỆ ĐIỀU HÀNH Đề tài: XỬ LÝ VẤN ĐỀ DEADLOCK Giảng viên hướng dẫn: TS. Nguyễn Thanh Bình Sinh viên thực hiện: Nguyễn Văn Hiệp 20192838 Trần Ngọc Hạ 20192818 Nguyễn Thắng Đạt 20192748 Trần Đình Huỳnh 20192921 Hà Nội, 12-2022 LỜI NÓI ĐẦU Trong môi trường đa chương trình, nhiều tiến trình có thể cạnh tranh với nhau để được sử dụng một số tài nguyên. Một tiến trình yêu cầu tài nguyên, nếu tài nguyên không sẵn dùng tại thời điểm đó, tiến trình đi vào trạng thái chờ đợi. Quá trình chờ có thể không bao giờ chuyển trạng thái vì tài nguyên chúng yêu cầu bị giữ bởi những tiến trình đang chờ đợi khác. Trường hợp này được gọi là deadlock (khoá chết). Chúng ta sẽ mô tả các phương pháp mà hệ điều hành có thể dùng để ngăn chặn hay giải quyết deadlock. Vấn đề deadlock có thể trở thành vấn đề phổ biến bởi xu hướng ngày càng tăng số lượng lớn quá trình, chương trình đa luồng, nhiều tài nguyên trong hệ thống. Chính vì thế, nhóm chúng em xin nghiên cứu đề tài “Tối ưu hóa bài toán deadlock – CPU affinity. ” Với đề tài này, chúng ta có thể hiểu nguyên nhân gây ra tình trạng deadlock và cách xử lý tình trạng deadlock hiệu quả.Mặc dù, chúng em đã cố gắng hoàn thành đồ án nghiên cứu của mình nhưng chắc chắn sẽ không tránh khỏi được những hạn chế và thiết sót. Em mong nhận được sự thông cảm và ý kiến đóng góp của các thầy cô để em có thể rút kinh nghiệm và hoàn thiện đề tài tốt hơn. MỤC LỤC DANH MỤC KÝ HIỆU VÀ CHỮ VIẾT TẮT ........................................................................ i DANH MỤC HÌNH VẼ ............................................................................................................ii DANH MỤC BẢNG BIỂU......................................................................................................iii CHƯƠNG 1. CHƯƠNG MỞ ĐẦU ......................................................................................... 4 1.1 Động lực nghiên cứu ...................................................................................................... 4 1.2 Phạm vi và đối tượng nghiên cứu ................................................................................. 4 1.3 Bố cục đồ án.................................................................................................................... 4 1.4 Kết luận chương ............................................................................................................. 5 CHƯƠNG 2. CƠ SỞ LÝ THYẾT ........................................................................................... 6 2.1 Deadlock ......................................................................................................................... 6 2.1.1 Deadlock là gì? ........................................................................................................ 6 2.1.2 Mô hình hệ thống ..................................................................................................... 7 2.1.3 Điều kiện xảy ra deadlock ........................................................................................ 7 2.1.4 Đồ thị cấp phát tài nguyên ....................................................................................... 8 2.1.5 Các phương pháp giải quyết deadlock ................................................................... 10 2.1.6 Ngăn deadlock ....................................................................................................... 10 2.1.7 Tránh deadlock ....................................................................................................... 11 2.1.8 Giải thuật banker .................................................................................................... 11 2.1.9 Hiệu chỉnh tắc nghẽn.............................................................................................. 13 2.2 Giới thiệu về mutex lock .............................................................................................. 13 2.2.1 Mutex lock là gì ..................................................................................................... 13 2.2.2 Mutex lock làm việc như thế nào? ......................................................................... 14 2.2.3 Vấn đề của deadlock với mutex ............................................................................. 15 2.3 Bài toán DINNING PHILOSOPHER ........................................................................ 17 CHƯƠNG 3. GIẢI PHÁP VÀ TỐI ƯU ................................................................................ 20 CHƯƠNG 4. KẾT QUẢ THỰC NGHIỆM .......................................................................... 20 KẾT LUẬN ............................................................................................................................. 21 Kết luận chung ................................................................................................................... 21 Hướng phát triển ............................................................................................................... 21 CHƯƠNG 5. TÀI LIỆU THAM KHẢO .............................................................................. 22 DANH MỤC KÝ HIỆU VÀ CHỮ VIẾT TẮT RAG Resource allocation graph i DANH MỤC HÌNH VẼ Hình 2.1 Minh họa 2 tiến trình xảy ra tình trạng deadlock ............................................ 6 Hình 2.2 Ví dụ về đồ thị cấp phát tài nguyên ................................................................. 9 Hình 2.3 RAG và deadlock ............................................................................................ 9 Hình 2.4 Cách sử dụng mutex để đồng bộ hóa luồng .................................................. 14 Hình 2.5 Hai task không thể tiến hành ......................................................................... 16 Hình 2.6 Bài toán bữa tối của các triết gia ................................................................... 17 Hình 2.7 Sơ đồ khối của bài toán ................................................................................. 18 Hình 2.8 Sơ đồ khối giải pháp deadlock ...................................................................... 19 DANH MỤC BẢNG BIỂU iii CHƯƠNG 1. CHƯƠNG MỞ ĐẦU Chương mở đầu sẽ nêu ra động lực nghiên cứu, đối tượng và phạm vi nghiên cứu song song với đó là trình bày bố cục đồ ấn và tóm tắt nội dung tương ứng của các phần. 1.1 Động lực nghiên cứu Xu hướng hiện nay là một máy tính có thể xử lý được số lượng lớn quá trình, chương trình đa luồng, nhiều tài nguyên trong hệ thống và đặc biệt các tập tin có đời sống dài. Cùng một lúc phải xử lý nhiều quá trình, khiến máy tính có thể xảy ra hiện tượng deadlock. Tình trạng deadlock xảy ra sẽ khiến quá trình làm việc của người sử dụng bị dừng lại. Vì vậy, nhóm chúng em đã quyết định tìm hiểu cách để xử lý vấn đề deadlock 1.2 Phạm vi và đối tượng nghiên cứu Việc xử lý được vấn đề deadlock sẽ giúp chúng ta tối ưu hóa được tài nguyên, không xảy ra các vấn đề khi đang sử dụng. Ở trong báo cáo này chúng em chỉ nghiên cứu trong phạm vi khu vực trường học, đối tượng nghiên cứu cụ thể là các tiến trình. 1.3 Bố cục đồ án Báo cáo môn học: Tối ưu hóa bài toán deadlock – cpu affinity được chia thành 4 chương. Chương 1: Chương mở đầu Phần này nêu ra động lực của báo cáo, giới hạn phạm vi nghiên cứu mà báo cáo tập trung giải quyết. Phần này cũng giới thiệu tóm tắt cấu trúc của báo cáo và nội dung tương ứng của các phần sẽ lần lượt được trình bày ở các chương tiếp theo. Chương 2: Cơ sở lý thuyết Phần này nêu ra cơ sở lý thuyết cơ bản được sử dụng trong báo cáo . Chương 3: Giải pháp và tối ưu. Chương 4: Kết quả thực hiện. Đây là chương cuối cùng của báo cáo. Phần này trình bày những kết quả mà báo cáo nghiên cứu đã đạt được từ đó đưa ra nhận xét, đánh giá. 1.4 Kết luận chương Phần mở đầu đã chỉ rõ được động lực nghiên cứu, phạm vi và đối tượng nghiên cứu của báo cáo, phân chia cấu trúc báo cáo và chỉ rõ nội dung tóm tắt của từng phần. CHƯƠNG 2. CƠ SỞ LÝ THYẾT Phần này nêu tổng quan lý thuyết được sử dụng, giới thiệu sơ lược về định nghĩa deadlock, mô hình hệ thống, phân bổ tài nguyên, nguyên nhân và cách xử lý tình trạng deadlock. 2.1 Deadlock 2.1.1 Deadlock là gì? Một tập hợp các tiến trình gọi là ở tình trạng tắc nghẽn nếu mỗi tiến trình trong tập hợp đều chờ đợi tài nguyên mà tiến trình khác trong tập hợp đang chiếm giữ. Ví dụ, tại một thời điểm tiến trình 1 đang giữ tài nguyên R1, yêu cầu R2 và tiến trình 2 đang giữ tài nguyên R2, yêu cầu R1. Như vậy yêu cầu tài nguyên không thể đáp ững cho cả hai tiến trình. Khi đó, không có tiến trình nào có thể tiếp tục xử lý, cùng như giải phóng tài nguyên cho các tiến trình khác sử dụng, tất cả các tiến trình trong tập hợp đều bị khóa vĩnh viễn. Assigned to Resource 1 Waiting to Process 1 Process 2 Resource 2 Waiting to Assigned to Hình 2.1 Minh họa 2 tiến trình xảy ra tình trạng deadlock 2.1.2 Mô hình hệ thống Hệ thống gồm các loại tài nguyên, kí hiệu R1, R2, R3, …., Rm Tài nguyên: CPU cycle, không gian, không gian bộ nhớ, thiết bị I/O, file Mỗi một loại tài nguyên Ri có Wi thực thể (instance). Process sử dụng tài nguyên theo thứ tự Yêu cầu (request): process phải chờ nếu yêu cầu không được đáp ứng ngay. Sử dụng (use): process sử dụng tài nguyên. Hoàn trả (release): process hoàn trả tài nguyên. Các tác vụ yêu cầu và hoàn trả được gọi qua system call. Ví dụ: Request/ release device Open/ close file Allocate/ free memory (cấp phát/ giải phóng bộ nhớ). 2.1.3 Điều kiện xảy ra deadlock Trường hợp deadlock có thể phát sinh nếu bốn điều kiện sau xảy ra cùng một lúc trong hệ thống: 1.Loại trừ tương hỗ (mutual exclusion): một tài nguyên có thể cấp phát cho nhiều lắm là 1 quá trình (tức là không chia sẻ tài nguyên được). Nếu một quá trình khác yêu của tài nguyên đó, quá trình yêu cầu phải tạm dừng cho đến khi tài nguyên được giải phóng. 2. Giữ và chờ (hold and wait): một quá trình phải đang giữ ít nhất một tài nguyên và đang chờ để nhận tài nguyên thêm mà hiện đang được giữ bởi quá trình khác. 3. Không đòi lại tài nguyên từ quá trình đang giữ chúng (no preemption): Không lấy lại tài nguyên đã cấp phát cho quá trình, ngoại trừ khi quá trình tự nó hoàn trả tài nguyên. 4. Tồn tại chu trình trong đồ thị cấp phát tài nguyên (circular wait): một tập hợp các quá trình {P0, P1,…,Pn} đang chờ sao cho: P0 đang chờ một tài nguyên được giữ bởi P1, P1 đang chờ tài nguyên đang giữ bởi P2,…, Pn-1 đang chờ tài nguyên đang được giữ bởi quá trình P0. 2.1.4 Đồ thị cấp phát tài nguyên Resource allocation graph (RAG): là đồ thị có hướng, với tập đỉnh V và tập cạnh E. Tập đình V gồm 2 loại: P = {P1, P2, P3,…, Pn} (tất cả các process trong hệ thống) R = {R1, R2, R3,…, Rn} (tất cả các loại tài nguyên trong hệ thống) Tập E gồm 2 loại: Request edge: cạnh có hướng từ Pi đến Rj Assignment edge: cạnh có hướng từ Rj đến Pi Kí hiệu Process: Loại tài nguyên với 4 thực thể: Pi yêu cầu một thực thể của Rj: Pi đang giữ một thực thể của Rj: Ví dụ về RAG Hình 2.2 Ví dụ về đồ thị cấp phát tài nguyên RAG và deadlock Ví dụ một RAG chứa chu trình nhưng không xảy ra deadlock: trường hợp P4 trả lại instance của R2. Hình 2.3 RAG và deadlock RAG không chứa chu trình không có deadlock RAG chứa một (hay nhiều) chu trình Nếu mỗi loại tài nguyên chỉ có một thực thể deadlock Nếu mỗi loại tài nguyên có nhiều thực thể có thể xảy ra deadlock 2.1.5 Các phương pháp giải quyết deadlock Có ba cách để xử lý Deadlock: 1. Phòng ngừa hoặc tránh bế tắc: Ý tưởng là không để hệ thống rơi vào trạng thái bế tắc. o Ngăn deadlock: không cho phép (ít nhất) một trong 4 điều kiện cần cho deadlock (Ngăn chặn được thực hiện bằng cách phủ nhận một trong những điều kiện cần thiết đã đề cập ở trên đối với bế tắc). o Tránh deadlock: Bằng cách sử dụng chiến lược “Tránh né”, chúng ta phải đưa ra một giả định. Chúng tôi cần đảm bảo rằng tất cả thông tin về tài nguyên mà quy trình sẽ cần đều được chúng tôi biết trước khi thực hiện quy trình. Để hệ thống có thể cấp phát tài nguyên một cách phù hợp 2. Phát hiện và khôi phục deadlock: Để xảy ra deadlock, sau đó thực hiện quyền ưu tiên để xử lý nó khi nó xảy ra. 3. Bỏ qua hoàn toàn vấn đề: Deadlock không được phát hiện, dẫn đến việc giảm hiệu suất của hệ thống. Cuối cùng hệ thống phải ngưng hoạt động và phải được khởi động lại. Đây là cách tiếp cận mà cả Windows và UNIX đều áp dụng 2.1.6 Ngăn deadlock 1. Ngăn mutual exclusion (loại trừ tương hỗ) Đối với tài nguyên không chia sẻ: không làm được Đối với sharable resource ( tài nguyên chia sẻ ví dụ như: read only file và tác vụ cho phép lên file chỉ là đọc): không cần thiết. 2. Ngăn giữ và chờ: Cách 1: mỗi process yêu cầu toàn bộ tài nguyên cần thiết 1 lần. Nếu đủ tài nguyên thì hệ thống sẽ cấp phát, nếu chưa đủ tài nguyên thì process sẽ bị blocked. Cách 2: khi yêu cầu tài nguyên, process đang giữ bất cứ tài nguyên nào thì phải trả lại trước khi yêu cầu. Hai cách đều dẫn đến hiệu suất sử dụng tài nguyên thấp. 3. Ngăn no preemption: cho phép lấy lại tài nguyên đã cấp phát cho quá trình (chỉ thích hợp với các loại tài nguyên dễ lưu và phục hồi như cpu, register, vùng nhớ; không thích hợp với các loại tài nguyên DVD, drive). 4. Ngăn circular wait: ta sẽ gán thứ tự cho các loại tài nguyên của hệ thống. Mỗi process yêu cầu thực thể của tài nguyên theo thứ tự tăng dần của loại tài nguyên. 2.1.7 Tránh deadlock Với ngăn deadlock, tài nguyên sẽ không được sử dụng hiệu quả Tránh deadlock: mỗi quá trình phải khai báo số lượng tài nguyên tối đa nó cần. Giải thuật tránh deadlock sẽ điều khiển trạng thái cấp phát tài nguyên sao cho hệ thống không rơi vào deadlock. Trạng thái cấp phát tài nguyên được định nghĩa bởi: số tài nguyên còn lại, số tài nguyên đã được cấp phát, và yêu cầu tối đa của mỗi process. 2.1.8 Giải thuật banker Áp dụng cho hệ thống cấp phát tài nguyên trong đó mỗi loại tài nguyên có thể có nhiều thực thể. Điều kiện: Mỗi tiến trình phải khai báo số lượng thực thể tối đa của mỗi loại tài nguyên mà nó cần. Khi tiến trình yêu cầu tài nguyên thì có thể phải đợi mặc dù tài nguyên được yêu cầu đang có sẵn. Khi tiến trình đã có được đầy đủ tài nguyên thì phải hoàn trả trong một khoảng thời gian hữu hạn nào đó. Giải thuật banker gồm: Giải thuật kiểm tra trạng thái an toàn Giải thuật cấp phát tài nguyên Giải thuật phát hiện deadlock 2.1.8.1 Giải thuật kiểm tra trạng thái an toàn Khi có tiến trình yêu cầu các tài nguyên, hệ điều hành thử cấp phát, sau đó xác định hệ thống có an toàn không (sử dụng giải thuật xác định trạng thái an toàn). Nếu hệ thống an toàn thì cấp phát thực sự các tài nguyên mà tiến trình yêu cầu, ngược lại tiến trình phải đợi. Ta có: n là số tiến trình, m: số loại tài nguyên Các cấu trúc dữ liệu Available: Đây là mảng 1 chiều có kích thước m cho biết số lượng tài nguyên có sẵn của mỗi loại được cấp vào chương trình Max: đây là mảng hai chiều có kích thước n*m xác định nhu cầu tối đa của mỗi tiến trình trong hệ thống. Allocation: nó là một mảng 2 chiều có kích thước n*m xác định số lượng tài nguyên của mỗi loại hiện hành đã được phân bố cho mội tiến trình. Need: nó là một mảng 2 chiều có kích thước n*m cho biết nhu cầu tài nguyên còn thiếu của mỗi tiến trình. Need [i, j] = Max [i, j] – Allocation [i, j] Tìm một chuỗi an toàn 1. Gọi Work và Finish là hai vecto độ dài m và n. khởi tạo Work available Finish [i] false, i= 1,…,n 2. Tìm i thỏa mãn Finish [i] = false Needi nhỏ hơn hoặc bằng Work (hàng thứ i của need) 3. Work Work + Allocationi Finish [i] true Quay về bước 2 4. Nếu Finish [i] = true, i= 1,…,n thì hệ thống đang ở trạng thái safe. 2.1.8.2 Giải thuật phát hiện deadlock Nếu khi tiến trình yêu cầu tài nguyên mà hệ thống cứ cấp phát thì tình trạng tắc nghẽn có thể xảy ra, khi đó hệ thống cần cung cấp giải thuật phát hiện tắc nghẽn và phục hồi tình trạng trước khi tắc nghẽn. Tài nguyên chỉ có một thể hiện: Dùng đồ thị hàng đợi, đồ thị này được xây dựng từ đồ thị cấp phát tài nguyên bằng các bỏ những đỉnh biểu diễn loại tài nguyên. Hệ thống bị tắc nghẽn chỉ khi đồ thì đợi tài nguyên có chu trình, do đó để phát hiện tắc nghẽn ta chỉ cần dùng giải thuật phát hiện chu trình. Tài nguyên có nhiều thể hiện: Ta có thể sử dụng giải thuật để phát hiện tắc nghẽn: Bước 1: chọn Pi đầu tiên sao cho có yêu cầu tài nguyên có thể đáp ứng, nếu không có thì hệ thống bị tắc nghẽn, ngược lại xuống bước 2 Bước 2: thử cấp phát tài nguyên cho Pi và kiểm tra trạng thái hệ thống, nếu hệ thống an toàn thì tới bước 2, ngược lại thì quay lại bước 1 để tìm Pi tiếp Bước 3: cấp phát tài nguyên cho Pi, nếu tất cả các Pi được đáp ứng thì hệ thống không bị tắc nghẽn, ngược lại quay lại bươc 2.1.9 Hiệu chỉnh tắc nghẽn Khi đã phát hiện tắc nghẽn, có hai lực chọn chính để xử lý: Hủy tiến trình trong tình trạng tắc nghẽn: Hủy tất cả các tiến trình trong tình trạng tắc nghẽn hay hủy từng tiến trình liên quan (dựa vào độ ưu tiên, thời gian đã xử lý, số lượng tài nguyên đang chiếm giữ, số lượng tài nguyên còn cần thêm..) cho đến khi không còn chu trình gây tắc nghẽn. Thu hồi tài nguyên: Thu hồi tài nguyên đã cấp phát và cấp phát lại cho các tiến trình khác cho đến khi không xảy ra tình trạng tắc nghẽn. 2.2 Giới thiệu về mutex lock 2.2.1 Mutex lock là gì Mutex là một khóa được đặt trước khi sử dụng một tài nguyên được chia sẻ và được giải phóng sau khi sử dụng tài nguyên đó. Khi khóa được đặt, không luồng nào khác có thể truy cập vào vùng mã bị khóa. Vì vậy, ngay cả khi luồng 2 được lập lịch trong khi luồng 1 chưa được thực hiện truy cập tài nguyên được chia sẻ và mã bị khóa bởi luồng 1 bằng mutex thì luồng 2 thậm chí không thể truy cập vùng mã đó. Vì vậy, điều này đảm bảo truy cập đồng bộ các tài nguyên được chia sẻ trong mã. 2.2.2 Mutex lock làm việc như thế nào? Hình 2.4 Cách sử dụng mutex để đồng bộ hóa luồng Giả sử một luồng đã khóa một vùng mã bằng mutex và đang thực thi đoạn mã đó. • Bây giờ schedule (bộ lập lịch) quyết định thực hiện chuyển đổi ngữ cảnh, thì tất cả các luồng khác đã sẵn sàng thực thi cùng một vùng sẽ được bỏ chặn. • Chỉ một trong số tất cả các luồng sẽ thực hiện nó nhưng nếu luồng này cố gắng thực thi cùng một vùng mã đã bị khóa thì nó sẽ lại chuyển sang trạng thái sleep. • Quá trình chuyển đổi ngữ cảnh sẽ diễn ra lặp đi lặp lại nhưng không luồng nào có thể thực thi vùng mã bị khóa cho đến khi khóa mutex trên nó được giải phóng. • Khóa Mutex sẽ chỉ được giải phóng bởi luồng đã khóa nó. Vì vậy, điều này đảm bảo rằng một khi một luồng đã khóa một đoạn mã thì không một luồng nào khác có thể thực thi cùng một vùng cho đến khi nó được mở khóa bởi luồng đã khóa nó. Một mutex được khởi tạo và sau đó khóa đạt được bằng cách gọi hai hàm sau: Hàm đầu tiên khởi tạo mutex và thông qua hàm thứ hai, bất kỳ vùng quan trọng nào trong mã đều có thể bị khóa. int pthread_mutex_init (pthread_mutex_t * limit mutex, const pthread_mutexattr_t * limit attr): Tạo mutex, được tham chiếu bởi mutex, với các thuộc tính được chỉ định bởi attr. Nếu attr là NULL, thuộc tính mutex mặc định (NONRECURSIVE) sẽ được sử dụng. Giá trị trả về : • Nếu thành công, pthread_mutex_init () trả về 0 và trạng thái của mutex sẽ được khởi tạo và mở khóa. • Nếu không thành công, pthread_mutex_init () trả về -1. int pthread_mutex_lock (pthread_mutex_t * mutex): Khóa một đối tượng mutex, xác định một mutex. Nếu mutex đã bị khóa bởi một luồng khác, thì luồng đó sẽ đợi mutex khả dụng. Chuỗi đã khóa mutex trở thành chủ sở hữu hiện tại của nó và vẫn là chủ sở hữu cho đến khi chính chuỗi đó đã mở khóa nó. Khi mutex có thuộc tính đệ quy, việc sử dụng khóa có thể khác. Khi loại mutex này bị khóa nhiều lần bởi cùng một chuỗi, thì số lượng sẽ tăng lên và không có chuỗi chờ nào được đăng. Luồng sở hữu phải gọi pthread_mutex_unlock () cùng một số lần để giảm số lượng xuống 0. Giá trị trả về: • Nếu thành công, pthread_mutex_lock () trả về 0. • Nếu không thành công, pthread_mutex_lock () trả về -1. Có thể mở khóa và phá hủy mutex bằng cách gọi hai chức năng sau: Chức năng đầu tiên giải phóng khóa và chức năng thứ hai phá hủy khóa để nó không thể được sử dụng ở bất kỳ đâu trong tương lai. int pthread_mutex_unlock (pthread_mutex_t * mutex): Giải phóng một đối tượng mutex. Nếu một hoặc nhiều luồng đang chờ khóa mutex, thì pthread_mutex_unlock () sẽ khiến một trong những luồng đó trả về từ pthread_mutex_lock () với đối tượng mutex được lấy. Nếu không có chủ đề nào đang chờ mutex, mutex sẽ mở khóa mà không có chủ sở hữu hiện tại. Khi mutex có thuộc tính đệ quy, việc sử dụng khóa có thể khác. Khi loại mutex này bị khóa nhiều lần bởi cùng một chuỗi, thì việc mở khóa sẽ giảm số lượng và không có chuỗi chờ nào được đăng để tiếp tục chạy với khóa. Nếu số lượng giảm xuống 0, thì mutex sẽ được giải phóng và nếu bất kỳ luồng nào đang chờ nó sẽ được đăng. Giá trị trả về: • Nếu thành công, pthread_mutex_unlock () trả về 0. • Nếu không thành công, pthread_mutex_unlock () trả về -1 int pthread_mutex_destroy (pthread_mutex_t * mutex): Xóa một đối tượng mutex, xác định một mutex. Mutexes được sử dụng để bảo vệ tài nguyên được chia sẻ. mutex được đặt thành một giá trị không hợp lệ, nhưng có thể được khởi động lại bằng cách sử dụng pthread_mutex_init (). Giá trị trả về • Nếu thành công, pthread_mutex_destroy () trả về 0. • Nếu không thành công, pthread_mutex_destroy () trả về -1 2.2.3 Vấn đề của deadlock với mutex Trong một hệ điều hành thường có nhiều hơn một tác vụ (Task). Mutex giúp hai task sẽ không cho phép hai Task truy cập vào tài nguyên hệ thống trong cùng một thời điểm. Deadlock chính là một cạm bẫy tiềm ẩn của việc sử dụng Mutexes để loại trừ lẫn nhau. Deadlock xảy ra khi khi hai Task không thể tiến hành do cả hai đang chờ đợi resource và bị giữ bỏ task còn lại. Ví dụ: Hình 2.5 Hai task không thể tiến hành Có 2 Task A, Task B, 2 mutex: mutex1 và mutex2. Task A được thực hiện và lấy thành công mutex1. Task A bị pre-empted bởi Task B. Task B thành công lấy mutex2 trước khi cố gắng lấy mutex1- cái đang bị giữ bởi Task A nên không có sẵn lúc này. Do đó Task B rơi vào trạng thái Block và chờ mutex1 được release. Task A tiếp tục thực hiện, có gắng lấy mutex2- cái đang được giữ bởi TaskB nên cũng không có sẵn lúc này. Do đó Task A cũng rơi vào trạng thái Block đợi mutex2 được release . Kết quả là Task A đợi mutex2 bị giữ bởi TaskB và ngược lại Task B đợi mutex1 bị giữ bởi Task A. Deadlock xảy ra. 2.3 Bài toán DINNING PHILOSOPHER Đây là bài toán kinh điển về đồng bộ hóa. Nó trình bày quá trình cấp phát tài nguyên giữa các tiến trình mà không bị deadlock hay đói tài nguyên. Bài toán: Bài toán bữa tối các triết gia đặt ra giả thiết rằng có K nhà triết học ngồi xung quanh một chiếc bàn tròn với một chiếc đũa giữa mỗi cặp triết gia. Có một chiếc đũa giữa mỗi nhà triết học. Một triết gia có thể ăn nếu anh ta cầm được hai chiếc đũa liền kề với mình. Một chiếc đũa có thể được nhặt bởi bất kỳ ai trong số những người đi heo bên cạnh của nó nhưng không được cả hai. Bài toán đặt ra là làm thế nào để không có nhà triết học nào bị đói Hình 2.6 Bài toán bữa tối của các triết gia Giải pháp: Trong trường hợp này, ta giả sử có 5 nhà triết học đang ngồi trong một bàn tròn. Các triết gia được đánh số từ 0 đến 4 tương tự như thế thì các chiếc đũa cũng được đánh số từ 0 đến 4. Tình huống giả lập được đưa ra như sau: Các nhà triết học sẽ có các trạng thái đó là THINKING, PUTUP, EAT, PUTDOWN Có hai tình huống giả lập được đưa ra đó là: + Tình huống 1: Các triết gia lần lượt thực hiện các hoạt động: Kiểm tra đũa, lấy đũa lên, bắt đầu ăn cuối cùng là đặt đũa xuống và lại lặp lại vòng đó. Khi thời gian kiểm tra đũa và thời gian ăn thỏa mãn thì sẽ không xảy ra deadlock +Tình huống 2: Giả sử Triết gia 0 đang cầm chiếc đũa thứ 0 và đợi chiếc đũa thứ 1. Triết gia 1 đang cầm chiếc đũa thứ 1 và đợi chiếc đũa thứ 2. Triết gia 2 đang cầm chiếc đũa thứ 2 và đợi chiếc đũa thứ 3. Triết gia 3 đang cầm chiếc đũa thứ 3 và đợi chiếc đũa thứ 4. Triết gia 4 đang cầm chiếc đũa thứ 4 và đợi chiếc đũa thứ 0. Trong trường hợp này, mỗi triết gia chỉ cầm 1 chiếc đũa trong cùng một thời điểm, do đó không có triết gia nào có thể thực hiện hoạt động do không thể thỏa mãn yêu cầu có hai chiếc đũa. Do đó, trường hợp này Deaadlock xảy ra. Hình 2.7 Sơ đồ khối của bài toán Phương án giải quyết: Chọn 1 ông triết gia với id bất kỳ (ở đây chúng em chọn ông triết gia có ID = 1), cho ông ta ngủ trong một khoảng thời gian sleep_time đủ lớn, để khi tất cả những ông triết gia còn lại thực hiện xong hành động của mình thì ông triết gia thứ 1 mới tỉnh dậy là thực hiện nốt hành động của mình. Nhờ có thời gian ngủ sleep_time này thì hiện tượng xảy ra deadlock không còn xảy ra. Tuy nhiên, thời gian ngủ là bao nhiêu là đủ cho bài toán 5 ông triết gia. Hình 2.8 Sơ đồ khối giải pháp deadlock CHƯƠNG 3. GIẢI PHÁP VÀ TỐI ƯU CHƯƠNG 4. KẾT QUẢ THỰC NGHIỆM KẾT LUẬN Kết luận chung Hướng phát triển CHƯƠNG 5. TÀI LIỆU THAM KHẢO [1] "randomnerdtutorials," [Online]. https://randomnerdtutorials.com/projects-esp32/. Available: [2] "geeksforgeeks.org," [Online]. Available: https://www.geeksforgeeks.org/mutexlock-for-linux-thread-synchronization/. [3] "docs.oracle.com," [Online]. 01/820-0619/geosb/index.html. Available: [4] N. X. Hải, OPERATING SYSTEM, 2008. https://docs.oracle.com/cd/E19205-