Mẫu Báo cáo thực hành lần 5 | Môn Hệ điều hành
Đầu tiên ta tạo file sp.c. Khai báo các thư viện cần thiết, sử dụng thư viện pthread để tạo và quản lý luồng. Khai báo và khởi tạo biến sells và products có ban đầu là 0, MSSV=1172.Tài liệu giúp bạn tham khảo, củng cố kiến thức và ôn tập đạt kết quả cao
Trường: Trường Đại học Công nghệ Thông tin, Đại học Quốc gia Thành phố Hồ Chí Minh
Thông tin:
Tác giả:
Preview text:
Báo cáo thực hành môn Hệ điều hành - Giảng viên: Trần Hoàng Lộc.
Họ và tên: Võ Nhất Phương Mã số sinh viên: 22521172 Lớp: IT007.O14 HỆ ĐIỀU HÀNH BÁO CÁO LAB 5 CHECKLIST
5.5. BÀI TẬP THỰC HÀNH BT 1 BT 2 BT 3 BT 4 Trình bày cách làm
Chụp hình minh chứng
Giải thích kết quả
5.6. BÀI TẬP ÔN TẬP BT 1 Trình bày cách làm
Chụp hình minh chứng
Giải thích kết quả
Tự chấm điểm: 10
*Lưu ý: Xuất báo cáo theo định dạng PDF, đặt tên theo cú pháp: _LAB5.pdf 1
Báo cáo thực hành môn Hệ điều hành - Giảng viên: Trần Hoàng Lộc.
5.5. BÀI TẬP THỰC HÀNH
1. Hiện thực hóa mô hình trong ví dụ 5.3.1.2, tuy nhiên thay bằng điều kiện sau:
sells <= products <= sells + [4 số cuối của MSSV] Trả lời... • Trình bày cách làm:
o Đầu tiên ta tạo file sp.c. Khai báo các thư viện cần thiết, sử dụng thư viện
pthread để tạo và quản lý luồng.
o Khai báo và khởi tạo biến sells và products có ban đầu là 0, MSSV=1172
o Ta khai báo hàm thực thi công việc của tiến trình A: Đầu tiên ta sẽ sử dụng
hàm sem_wait(&sem) để kiểm tra giá trị của sem, nếu sem bằng 0 thì nó sẽ
bị block, nếu sem > 0 thì sẽ thực hiện lệnh sem = sem – 1 sau đó thực hiện
qua lệnh mới là lệnh sells++ thực hiện, có nghĩa là khi chúng ta muốn bán
được hàng thì phải có hàng trước đã. Vậy hàm sem_wait() mục đích là để
kiểm tra xem đã có hàng hay chưa, tiếp theo sử dụng hàm
sem_post(&sem1) để tăng giá trị của sem1 lên để làm điều kiện cho hàm process A.
o Ta khai báo hàm thực thi công việc của tiến trình B: Đây là hàm sử dụng để
sản xuất hang. Đầu tiên sử dụng hàm sem_wait(&sem1) để kiểm tra xem
sem1 có bằng 0 hay không (tương tự process_a). Mục đích để kiểm tra
products có bé hơn sells + MSSV hay không để thỏa mãn điều kiện, sau đó
tăng biến products lên và sử dụng hàm sem_post(&sem) để thông báo cho
process B biết là đã có hàng
o Tạo luồng cho tiến trình A: pthread_create(&pA, NULL, &processA, NULL);
o Tạo luồng cho tiến trình B: pthread_create(&pB, NULL, &processB, NULL); o Sells>10000 thì break; 2
Báo cáo thực hành môn Hệ điều hành - Giảng viên: Trần Hoàng Lộc.
• Chụp hình minh chứng:
• Giải thích kết quả: 3
Báo cáo thực hành môn Hệ điều hành - Giảng viên: Trần Hoàng Lộc. 4
Báo cáo thực hành môn Hệ điều hành - Giảng viên: Trần Hoàng Lộc.
Nhìn vào kết quả ta có thể thấy products luôn luôn lớn hơn sells và luôn luôn nhỏ hơn
sell_1 (sells + MSSV), thỏa mãn được điều kiện mà bài tập đã nêu ra. SELL1=SELL+1172
2. Cho một mảng a được khai báo như một mảng số nguyên có thể chứa n phần tử,
a được khai báo như một biến toàn cục. Viết chương trình bao gồm 2 thread chạy song song:
Một thread làm nhiệm vụ sinh ra một số nguyên ngẫu nhiên sau đó bỏ vào a.
Sau đó đếm và xuất ra số phần tử của a có được ngay sau khi thêm vào.
Thread còn lại lấy ra một phần tử trong a (phần tử bất kỳ, phụ thuộc vào
người lập trình). Sau đó đếm và xuất ra số phần tử của a có được ngay sau
khi lấy ra, nếu không có phần tử nào trong a thì xuất ra màn hình “Nothing in array a”. 5
Báo cáo thực hành môn Hệ điều hành - Giảng viên: Trần Hoàng Lộc.
Chạy thử và tìm ra lỗi khi chạy chương trình trên khi chưa được đồng bộ. Thực hiện đồng bộ hóa với semaphore. Trả lời...
Khi chưa đồng bộ hóa với semaphore: • Trình bày cách làm:
o Đầu tiên ta tạo file non_semaphore.c. Sau đó khai báo các thư viện cần thiết.
o Khai báo biến n chứa kích thước của mảng, biến dem=0 và mảng a để lưu trữ các phần tử.
o Hàm process1 sẽ chạy vô hạn và thêm phần tử vào mảng a khi dem < n.
Hàm này sử dụng rand() để tạo số ngẫu nhiên và them vào mảng a. Sau mỗi
lần them phần tử thì biến dem tăng lên 1. In ra “Total number of elements
in array a =” để hiện số phần tử.
o Hàm process2 cũng chạy vô hạn và loại bỏ phần tử khỏi mảng a khi dem
<= n. Nó di chuyển mỗi phần tử sang trái để ghi đè phần tử đầu tiên, giảm
dem sau mỗi lần xóa. Nếu dem=0, nó in ra thông báo rằng “Nothing in
array a” còn không thì in ra “Number of elements in array a =” để hiện số phần tử.
o Trong hàm main, nhập giá trị n. Sau đó, hai luồng t1, t2 được tạo ra để chạy
các hàm process1() và process2(). Chương tình tiếp tục chạy vô hạn với vòng lặp while(1). 6
Báo cáo thực hành môn Hệ điều hành - Giảng viên: Trần Hoàng Lộc. • Hình ảnh minh chứng: 7
Báo cáo thực hành môn Hệ điều hành - Giảng viên: Trần Hoàng Lộc.
• Giải thích kết quả: 8
Báo cáo thực hành môn Hệ điều hành - Giảng viên: Trần Hoàng Lộc. 9
Báo cáo thực hành môn Hệ điều hành - Giảng viên: Trần Hoàng Lộc.
o Vì chưa có semaphore nên chương trình chưa được đồng bộ. Lỗi logic dùng
semaphore để xử lý lỗi logic. Các tiểu trình chạy không đồng đều, tiến trình
A không chạy được mà B cứ lấy ra kích thước của mảng nên số lượng phần
tử chỉ giảm chứ không tăng.
Khi đồng bộ hóa với semaphore • Trình bày cách làm:
o Đầu tiên ta tạo file semaphore. C, sau đó khai báo các thư viện cần thiết.
o Khai báo 2 biến Semaphore sem1, sem2 để sử dụng trong chương trình.
o Khai báo biến n để lưu trữ kích thước của mảng và biến i là chỉ số của mảng.
o Khai báo biến static dem để đảm bảo rằng giá trị biến dem không bị mất
sau mỗi lần process1 và process2 được gọi. Mọi sự thay đổi của dem trong
một hàm sẽ ảnh hưởng đến giá trị của dem trong hàm khác.
o Khai báo mảng a để lưu trữ các phần tử.
o Hàm process1 kiểm tra xem số lượng phần tử trong mảng a (dem) có nhỏ
hơn n hay không. Nếu điều kiện này đúng, một phần tử mới sẽ được thêm
vào mảng a. a[i++] = rand() % (n - 1);: Thêm một phần tử ngẫu nhiên vào
mảng a. Biến i là chỉ số của mảng và sau mỗi lần gán giá trị, nó sẽ tăng lên
để trỏ đến vị trí tiếp theo trong mảng. dem++;: Tăng biến dem lên để chỉ ra
rằng có một phần tử mới đã được thêm vào mảng. Sau đó in ra số lượng
phần tử hiện tại trong mảng a. int time_sleep = rand() % 2 + 1;
sleep(time_sleep);: Tạo một thời gian ngẫu nhiên để dừng hàm một khoảng
thời gian ngẫu nhiên trước khi tiếp tục. sem_post(&sem1);: Tăng giá trị của 10
Báo cáo thực hành môn Hệ điều hành - Giảng viên: Trần Hoàng Lộc.
Semaphore sem1, thông báo rằng một phần tử mới đã được thêm vào mảng
và process2() có thể tiếp tục thực hiện.
o Hàm process2 đợi Semaphore sem1. Nếu giá trị của nó không phải là 0,
tiến hành kiểm tra và xóa phần tử khỏi mảng a. Kiểm tra xem mảng có rỗng
không. Nếu rỗng, in ra thông báo. dem--;: Giảm số lượng phần tử trong
mảng để chỉ ra rằng một phần tử đã bị xóa. b = a[0]; for (j = 0; j < dem;
j++) { a[j] = a[j + 1]; }: Dịch chuyển tất cả các phần tử trong mảng sang
trái để xóa phần tử đầu tiên. In ra số lượng phần tử hiện tại trong mảng a
sau khi đã xóa. int time_sleep = rand() % 2 + 1; sleep(time_sleep);: Tạo
một thời gian ngẫu nhiên để dừng hàm một khoảng thời gian ngẫu nhiên trước khi tiếp tục.
o sem_init(&sem1, 1, 0);: Khởi tạo Semaphore sem1 với giá trị ban đầu là 0
và sử dụng để đồng bộ hóa các hoạt động giữa hai luồng.
o sem_init(&sem2, 0, 0);: Khởi tạo Semaphore sem2 với giá trị ban đầu là 0.
o printf("\nEnter n: "); scanf("%d", &n);: Yêu cầu người dùng nhập kích
thước của mảng từ bàn phím.
o pthread_t th1, th2;: Khai báo hai biến để lưu trữ thông tin về luồng.
o pthread_create(&th1, NULL, PROCESS1, NULL);: Tạo luồng thứ nhất và
chạy hàm process1() trong đó.
o pthread_create(&th2, NULL, PROCESS2, NULL);: Tạo luồng thứ hai và
chạy hàm process () trong đó.
o while(1);: Vòng lặp vô hạn để chương trình tiếp tục chạy sau khi tạo các luồng. 11
Báo cáo thực hành môn Hệ điều hành - Giảng viên: Trần Hoàng Lộc. • Hình ảnh minh chứng: 12
Báo cáo thực hành môn Hệ điều hành - Giảng viên: Trần Hoàng Lộc.
• Giải thích kết quả:
o Semaphore sem1: Điều này đảm bảo rằng khi một phần tử mới được thêm
vào mảng (PUSH), sem_post(&sem1); sẽ được gọi để thông báo cho tiến
trình process2 () rằng có phần tử mới và có thể thực hiện POP.
o sem_wait(&sem1); trong process2(): Tiến trình process2() sẽ đợi cho đến
khi có thông báo từ sem_post(&sem1); để bắt đầu xóa phần tử từ mảng (POP).
o Kết quả của bạn cho thấy rằng PUSH và POP được thực hiện xen kẽ nhau
một cách đồng bộ và không có tình trạng đảo lộn. Điều này là kết quả của
việc sử dụng Semaphore để điều chỉnh thứ tự thực thi của hai tiến trình, 13
Báo cáo thực hành môn Hệ điều hành - Giảng viên: Trần Hoàng Lộc.
giúp tránh xung đột dữ liệu và đảm bảo tính đồng bộ trong các hoạt động trên mảng a.
3. Cho 2 process A và B chạy song song như sau: int x = 0; PROCESS A PROCESS B processA() processB() { { while(1){ while(1){ x = x + 1; x = x + 1; if (x == 20) if (x == 20) x = 0; x = 0; print(x); print(x); } } } }
Hiện thực mô hình trên C trong hệ điều hành Linux và nhận xét kết quả. Trả lời… • Trình bày cách làm:
o Đầu tiên ta tạo file process.c. Sau đó ta khai báo các thư viện cần thiết.
o Khai báo biến toàn cục x=0;
o Hàm processA được sử dụng để tăng giá trị của biến x lên 1 và nếu x đạt
giá trị 20, nó sẽ được đặt lại về 0. Sau đó, hàm in ra giá trị x trong "Process A".
o Hàm processB thực hiện công việc tương tự như processA, nhưng nó in ra
giá trị x dưới trong "Process B".
o Hàm main bắt đầu bằng cách khởi tạo hai luồng (t1 và t2) thông qua hàm
pthread_create. Luồng t1 được gán cho processA và luồng t2 được gán cho processB. 14
Báo cáo thực hành môn Hệ điều hành - Giảng viên: Trần Hoàng Lộc.
o Cuối cùng, chương trình tiếp tục thực thi với một vòng lặp vô hạn
(while(1)) để giữ cho các luồng chạy song song với nhau. • Hình ảnh minh chứng: 15
Báo cáo thực hành môn Hệ điều hành - Giảng viên: Trần Hoàng Lộc.
• Giải thích kết quả:
Chương trình đã bị lỗi vùng tranh chấp (CS). Trong chương trình trên vì cả hai
hàm processA và processB thực hiện câu lệnh như nhau nên nếu đúng thì kết quả
xuất ra phải liên tục x tăng dần thêm 1 đơn vị đến 20 lại trở về 0,nhưng ở kết quả trên, ta thấy: o
o Sau khi Process B x=14 thì tiếp theo A phải bằng 15 nhưng ở đây A cho kết
quả bằng 13. Bởi vì, khi process A thực thi vùng tranh chấp của mình thì
process B cũng thực thi vùng tranh chấp của mình nên xung đột xảy ra lỗi.
4. Đồng bộ với mutex để sửa lỗi bất hợp lý trong kết quả của mô hình Bài 3. Trả lời… 16
Báo cáo thực hành môn Hệ điều hành - Giảng viên: Trần Hoàng Lộc. • Trình bày cách làm:
o Đầu tiên ta tạo file mutex.c, sau đó khai báo các thư viện cần thiết.
o Khai báo mutex t: pthread_mutex_t t;
o Hàm thực thi processA: pthread_mutex_lock(&t); Khóa mutex t, ngăn chặn
thread khác gọi hàm này khi đang được thực thi. Sau khi thực thi xong thì
mở khoá mutex t, cho phép các thread khác được quyền tranh chấp được khoá mutex t.
o Hàm thực thi processB, tương tự như processA
o pthread_mutex_init(&t, NULL): Khởi tạo một mutex, được gọi là t, thông
qua hàm pthread_mutex_init. Mutex này sẽ được sử dụng để đồng bộ hóa
truy cập đến biến x trong các luồng processA và processB.
o Tạo luồng cho hàm processA và process.
o Chạy vô hạn trong khi 2 process thực thi song song. • Hình ảnh minh chứng:
• Giải thích kết quả: 17
Báo cáo thực hành môn Hệ điều hành - Giảng viên: Trần Hoàng Lộc.
Tại processA và processB ta dùng hàm pthread_mutex_lock() để khoá các process
khác và để process đang thực thi hoàn thành vùng tranh chấp của mình.
Sau khi hoàn thành vùng tranh chấp của mình các process dùng hàm
pthread_mutex_unlock() để thoát ra khỏi vùng tranh chấp và mở khoá cho các
process khác có thể nhảy vào thực thi vùng tranh chấp.
Sau khi chạy chương trình đã sửa lỗi, ta thấy chương trình đã chạy đúng như dự
đoán, vì cả 2 process đều cùng sử dụng các câu lệnh giống nhau nên các con số khi
xuất ra sẽ theo tuần tự logic.
5.6. BÀI TẬP ÔN TẬP 18
Báo cáo thực hành môn Hệ điều hành - Giảng viên: Trần Hoàng Lộc.
1. Biến ans được tính từ các biến x1, x2, x3, x4, x5, x6 như sau: w = x1 * x2; (a) v = x3 * x4; (b) y = v * x5; (c) z = v * x6; (d) y = w * y; (e) z = w * z; (f) ans = y + z; (g)
Giả sử các lệnh từ (a) → (g) nằm trên các thread chạy song song với nhau. Hãy lập
trình mô phỏng và đồng bộ trên C trong hệ điều hành Linux theo thứ tự sau:
(c), (d) chỉ được thực hiện sau khi v được tính
(e) chỉ được thực hiện sau khi w và y được tính
(g) chỉ được thực hiện sau khi y và z được tính Trả lời... • Trình bày cách làm:
o Đầu tiên ta tạo file bt_ontap.c, sau đó khai báo các thư viện cần thiết.
o sem_t p1_5, p1_6, p2_3, p2_4, p3_5, p4_6, p5_7, p6_7; khai báo các semaphore.
o Khởi tạo các giá trị x.
o int w, v, z, y, x; khai báo các biến trung gian trong quá trình tính toán ans.
o Trong hàm thực thi ProcessA: w=x1*x2; sau đó in ra w. sem_post(&p1_5);
sem_post(&p1_6);: dựa vào mối quân hệ giữa các process, ta thấy khi
process A được chạy nghĩa là w được tính thì e và f mới được phép chạy =>
ta dùng sem_post để mở block sem p1_5,p1_6. pthread_exit(NULL);kết thúc luồng.
o Trong hàm thực thi ProcessB; v=x3*x4; sau đó in ra v. sem_post(&p2_3);
sem_post(&p2_4);: dựa vào mối quân hệ giữa các process, ta thấy khi
process B được chạy nghĩa là v được tính thì c và d mới được phép chạy => 19
Báo cáo thực hành môn Hệ điều hành - Giảng viên: Trần Hoàng Lộc.
ta dùng sem_post để mở block sem p2_3,p2_4. pthread_exit(NULL);kết thúc luồng.
o Tương tự với các ProcessC, ProcessD, ProcessE, ProcessF, ProcessG
o Trong hàm main, ta khởi tạo các semaphore, Tạo các tiểu trình pthread_t
th1, th2, th3, th4, th5, th6, th7; Sau đó thực thi các tiểu trình. 20