Bài tập ôn tập 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) 25 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
IT007.O16 – Lab05: Làm việc với tiểu trình đồng hóa tiểu trình Section 5.5 Hiện thực hóa mơ hình ví dụ 5.3.1.2, nhiên thay điều kiện sau: sells lỗi Code C: #include #include #include int x = 0; void *processA(void* mess) { while (1) { x = x + 1; if (x == 20) x = 0; printf("ProcessA - x = %d\n", x); } } void *processB(void* mess) { while (1) { x = x + 1; if (x == 20) x = 0; printf("ProcessB - x = %d\n", x); } } int main() { pthread_t pA, pB; pthread_create(&pA, NULL, &processA, NULL); pthread_create(&pB, NULL, &processB, NULL); while (1) {} return 0; } - Chúng ta thực lại việc viết hai hàm tiến trình đề cho tiến trình chạy song song với cách tạo pthread GVHD: Lê Hoài Nghĩa 10 IT007.O16 – Lab05: Làm việc với tiểu trình đồng hóa tiểu trình - Kết chạy code Hình 3.5.3.1: Kết chạy code Hình 5.5.3.2: Kết chạy code - Nhận xét kết quả: o Sau thực chương trình câu 3, có nhận xét chương trình có lỗi vùng tranh chấp Nghĩa tiến trình A thực thi vùng tranh chấp tiến trình B thực thi vùng tranh chấp mình, dẫn đến xung đột xảy lỗi hình 3.1 3.2 trên, hàm processA GVHD: Lê Hoài Nghĩa 11 IT007.O16 – Lab05: Làm việc với tiểu trình đồng hóa tiểu trình processB thực câu lệnh nhau, nên kết xuất phải logic, liên tục lẫn o Ở hình 3.1, sau x = process A process B x phải 8, B lại o Tương tự hình 3.2, sau process B x = 13 ProcessA x phải 10, x lại 17 Đây lỗi vùng tranh chấp mà hai tiến trình tạo nên - Kết luận: khơng đồng tiến trình vùng tranh chấp khiến kết toán bị sai, bất hợp lý Đồng với mutex để sửa lỗi bất hợp lý kết mơ hình Bài Trả lời: - Ý tưởng: o Để sửa lỗi bất hợp lý kết mơ hình Bài 3, ta cần sử dụng mutex để đồng hóa truy cập vào biến x hai process A B o Khởi tạo Mutex: Trước bắt đầu sử dụng, ta cần khởi tạo biến mutex o Sử dụng Mutex Process A B: ▪ Trước thay đổi giá trị x, ta sử dụng pthread_mutex_lock để đảm bảo có process phép thay đổi giá trị ▪ Sau thay đổi x, ta sử dụng pthread_mutex_unlock để giải phóng mutex o Hủy Mutex: Khi khơng cần sử dụng nữa, hủy mutex để giải phóng tài nguyên o Với chế này, ta đảm bảo có process phép thay đổi giá trị biến x thời điểm, từ tránh race condition đảm bảo tính quán liệu - Hiện thực code: GVHD: Lê Hoài Nghĩa 12 IT007.O16 – Lab05: Làm việc với tiểu trình đồng hóa tiểu trình Hình 5.5.4.1 Chương trình C - Kết quả: GVHD: Lê Hoài Nghĩa 13 IT007.O16 – Lab05: Làm việc với tiểu trình đồng hóa tiểu trình Hình 5.5.4.2 Kết chương trình - Nhận Xét: o Race Condition giải quyết: Các giá trị x hiển thị không bị trùng lặp Process A Process B Điều cho thấy việc sử dụng mutex giải vấn đề race condition thành công o Chu kỳ lặp đắn: Các process thực chu kỳ lặp mà khơng gặp vấn đề đột ngột lỗi khơng mong muốn (điều nhận thấy rõ) o Mutex đảm bảo Tính Nhất Quán: Kết cho thấy tính quán liệu hai process thay đổi giá trị x Việc sử dụng mutex đảm bảo process thực thay đổi giá trị x thời điểm o Dòng in Process A Process B: Khi x đạt đến giá trị 19 tiếp tục tăng, Process B đặt lại x thành 0, theo Process A tiếp tục in giá trị Điều kết với logic mơ hình o Sự Chia Sẻ Rõ Ràng Process A B: Cả Process A Process B thực bước chu kỳ lặp mà khơng làm ảnh hưởng đến chu kỳ process khác, chia sẻ chúng quản lý cách an toàn - Kết luận: Kết thể việc sử dụng mutex giải vấn đề đồng thời mơ hình, đảm bảo tính quán liệu chia sẻ an toàn hai process GVHD: Lê Hoài Nghĩa 14 IT007.O16 – Lab05: Làm việc với tiểu trình đồng hóa tiểu trình Section 5.6 Biến ans tính từ biến x1, x2, x3, x4, x5, x6 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ử lệnh từ (a) → (g) nằm thread chạy song song với Hãy lập trình mơ đồng C hệ điều hành Linux theo thứ tự sau: • • • (c), (d) thực sau v tính (e) thực sau w y tính (g) thực sau y z tính Trả lời: - Code C: #include #include #include // Các biến đầu vào int x1, x2, x3, x4, x5, x6; // Các biến trung gian int w, v, y, z, ans; // Semaphores sem_t wy_sem, wz_sem, vy_sem, vz_sem, yy_sem, zz_sem, y_ans_sem, z_ans_sem; // Hàm tính tốn cho biến thỏa công thức // 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) void *calculate_w(void *arg) { GVHD: Lê Hoài Nghĩa 15 IT007.O16 – Lab05: Làm việc với tiểu trình đồng hóa tiểu trình w = x1 * x2; sem_post(&wy_sem); sem_post(&wz_sem); printf("w = %d\n", w); return NULL; } void *calculate_v(void *arg) { v = x3 * x4; sem_post(&vy_sem); sem_post(&vz_sem); printf("v = %d\n", v); return NULL; } void *calculate_y(void *arg) { sem_wait(&vy_sem); y = v * x5; sem_post(&yy_sem); printf("y = %d\n", y); return NULL; } void *calculate_z(void *arg) { sem_wait(&vz_sem); z = v * x6; sem_post(&zz_sem); printf("z = %d\n", z); return NULL; } void *calculate_yw(void *arg) { sem_wait(&wy_sem); sem_wait(&yy_sem); y = w * y; GVHD: Lê Hoài Nghĩa 16 IT007.O16 – Lab05: Làm việc với tiểu trình đồng hóa tiểu trình sem_post(&y_ans_sem); printf("y = %d\n", y); return NULL; } void *calculate_zw(void *arg) { sem_wait(&wz_sem); sem_wait(&zz_sem); z = w * z; sem_post(&z_ans_sem); printf("z = %d\n", z); return NULL; } void *calculate_ans(void *arg) { sem_wait(&y_ans_sem); sem_wait(&z_ans_sem); ans = y + z; printf("ans = %d\n", ans); return NULL; } int main() { // Khởi tạo semaphores sem_init(&wy_sem, 0, 1); sem_init(&wz_sem, 0, 1); sem_init(&vy_sem, 0, 1); sem_init(&vz_sem, 0, 1); sem_init(&yy_sem, 0, 1); sem_init(&zz_sem, 0, 1); sem_init(&y_ans_sem, 0, 1); sem_init(&z_ans_sem, 0, 1); // Nhập giá trị từ bàn phím cho x1 đến x6 printf("Nhap gia tri cho x1: "); scanf("%d", &x1); printf("Nhap gia tri cho x2: "); GVHD: Lê Hoài Nghĩa 17 IT007.O16 – Lab05: Làm việc với tiểu trình đồng hóa tiểu trình scanf("%d", &x2); printf("Nhap gia tri cho x3: "); scanf("%d", &x3); printf("Nhap gia tri cho x4: "); scanf("%d", &x4); printf("Nhap gia tri cho x5: "); scanf("%d", &x5); printf("Nhap gia tri cho x6: "); scanf("%d", &x6); // Khởi tạo thread pthread_t threads[7]; pthread_create(&threads[0], pthread_create(&threads[1], pthread_create(&threads[2], pthread_create(&threads[3], pthread_create(&threads[4], pthread_create(&threads[5], pthread_create(&threads[6], NULL, NULL, NULL, NULL, NULL, NULL, NULL, calculate_w, NULL); calculate_v, NULL); calculate_y, NULL); calculate_z, NULL); calculate_yw, NULL); calculate_zw, NULL); calculate_ans, NULL); // Join thread for (int i = 0; i < 7; i++) { pthread_join(threads[i], NULL); } // Hủy semaphores sem_destroy(&wy_sem); sem_destroy(&wz_sem); sem_destroy(&vy_sem); sem_destroy(&vz_sem); sem_destroy(&yy_sem); sem_destroy(&zz_sem); sem_destroy(&y_ans_sem); sem_destroy(&z_ans_sem); return 0; } GVHD: Lê Hoài Nghĩa 18 IT007.O16 – Lab05: Làm việc với tiểu trình đồng hóa tiểu trình - Kết quả: Hình 5.6.1: Kết chạy code -Hết - GVHD: Lê Hoài Nghĩa 19