1. Trang chủ
  2. » Công Nghệ Thông Tin

Bài giảng Chương 4: Luồng

32 1 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 32
Dung lượng 143,16 KB

Nội dung

Mời các bạn tham khảo Bài giảng Chương 4: Luồng sau đây để bổ sung thêm kiến thức về cách tạo luồng, truyền dữ liệu cho luồng, giá trị trả về của luồng, Thread ID, thuộc tính của luồng, Thread Cancelation và một số nội dung khác.

Chương Luồng Phạm Quang Dũng http://fita.hua.edu.vn/pqdung 4.1 Tạo luồng  Mỗi luồng tiến trình xác định thread ID  Trong C/C++, để dùng thread ID, sử dụng kiểu pthread_t  Chương trình truyền tham số cho luồng lấy liệu từ luồng qua giá trị trả  Sử dụng hàm pthread_create Các tham số hàm pthread_create Một trỏ tới biến kiểu pthread_t chứa ID luồng Một trỏ tới đối tượng thread attribute Đối tượng điều khiển chi tiết việc tiến trình tương tác với phần cịn lại chương trình Nếu truyền thread attribute NULL, luồng có thuộc tính mặc định Một trỏ tới hàm thread, hàm bình thường có kiểu: void* (*) (void*) Một giá trị thread argument có kiểu void* Bạn truyền đơn giản tham số cho hàm thread luồng bắt đầu thực  Lời gọi pthread_create trở lập tức,  luồng ban đầu thực tiếp lệnh sau lời gọi  đó, luồng bắt đầu thực hàm thread   Linux lập lịch luồng theo cách không đồng  Chương trình bạn phải khơng phụ thuộc vào thứ tự thực luồng Ví dụ  Listing 4.1 (thread-create.c): tạo luồng in ký tự ‘x’; sau gọi pthread_create, luồng in ký tự ‘o’  kết chạy chương trình?  Lý do: Linux luân phiên lập lịch luồng 4.1.1 Truyền liệu cho luồng      thread argument dùng để truyền liệu cho luồng Vì kiểu argument void* nên bạn truyền nhiều liệu trực tiếp thông qua Giải pháp? Dùng argument để truyền trỏ tới cấu trúc mảng liệu Listing 4.2: thread-create2.c  kết chạy chương trình?  lý do?   khơng có đảm bảo cho luồng (main) kết thúc sau luồng Giải pháp? 4.1.2 Joining Threads  Là chế đảm bảo đợi kết thúc luồng  Hàm pthread_join, có tham số:    Thread ID Con trỏ tới biến void* để nhận giá trị trả luồng kết thúc Nếu không quan tâm đến giá trị truyền cho kiểu NULL Listing 4.3: 4.1.3 Giá trị trả luồng  Nếu đối số thứ pthread_join khác NULL, giá trị trả luồng đặt vị trí trỏ đối số  Giá trị có kiểu void*, muốn kiểu khác cần ép kiểu sau gọi pthread_join  Listing 4.4 (primes.c): tính số nguyên tố thứ n luồng Luồng trả số nguyên tố mong muốn giá trị trả Trong luồng rỗi để thực việc khác 4.1.4 Nói thêm Thread ID  Đôi ta cần xác định luồng thực  Hàm pthread_self trả thread ID luồng mà hàm gọi  Vd ứng dụng: tránh lỗi luồng gọi pthread_join để join cách dùng mã sau: if(!pthread_equal(pthread_self(),other_thread) pthread_join(other_thread,NULL); 10 4.3 Đồng hóa Đoạn găng     Lập trình với luồng địi hỏi phải khéo léo hầu hết chương trình đa luồng chương trình đồng thời Khơng có cách biết hệ thống lập lịch luồng để chạy Một luồng chạy lâu, hệ thống chuyển luồng nhanh Trên hệ thống đa xử lý, chí hệ thống lập lịch nhiều luồng chạy nghĩa đồng thời Gỡ lỗi chương trình đa luồng khó khơng thể khiến hệ thống lập lịch luồng theo cách ổn định 18 4.3.1 Race Conditions     Là trạng thái luồng tranh thay đổi cấu trúc liệu Giả sử chương trình có job queue, biểu diễn danh sách liên kết Sau luồng kết thúc thực hiện, kiểm tra queue Nếu queue không rỗng, luồng loại bỏ job đầu danh sách, thiết lập job_queue cho job Listing 4.10: job-queue1.c 19      Giả sử luồng kết thúc job gần thời điểm, lại job queue Luồng kiểm tra job_queue có rỗng khơng; thấy cịn chứa trỏ tới next_job Đúng lúc này, Linux ngắt luồng lập lịch luồng Luồng kiểm tra job_queue gán trỏ tới next_job  luồng thực job 20    Để loại bỏ trạng thái tranh đua, bạn cần cách làm cho hoạt động nguyên tử (atomic) Một hoạt động nguyên tử hoạt động chia nhỏ bị ngắt Chỉ cho phép luồng truy nhập job queue thời điểm 21 4.3.2 Mutexes    MUTual EXclusion locks – hỗ trợ HĐH để thực thi việc loại bỏ trạng thái đua tranh Là khóa đặc biệt cho phép luồng khóa thời điểm, luồng khác bị chặn lại (blocked) Để khởi tạo mutex với thuộc tính mặc định: pthread_mutex_t mutex; pthread_mutex_init(&mutex, NULL);  Hoặc: pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER; 22   Luồng cố gắng khóa (giành lấy) mutex cách gọi pthread_mutex_lock:  mutex không bị khóa luồng giành  trái lại, luồng bị chặn thực (blocked) Có thể có nhiều luồng bị chặn, mutex mở khóa, luồng mở chặn giành mutex, luồng khác bị chặn  Mở khóa mutex: pthread_mutex_unlock  Listing 4.11: job-queue2.c 23 Hàm thêm job vào queue void enqueue_job(struct job* new_job) { pthread_mutex_lock(&job_queue_mutex); new_job->next = job_queue; job_queue = new_job; pthread_mutex_unlock(&job_queue_mutex); } 24 4.3.3 Nonblocking Mutex Tests  Dùng pthread_mutex_trylock thay pthread_mutex_lock  Nếu khơng giành mutex luồng gọi khơng bị chặn mà trở với mã lỗi EBUSY 25 4.3.4 Semaphores for Threads    Khi luồng thực nhanh, job queue bị rỗng, luồng thoát Sau đó, có thêm job vào queue, khơng cịn luồng để xử lý Cần chế chặn luồng queue rỗng có job  Giải pháp? semaphore (cờ báo)  Mỗi semaphore có giá trị đếm ngun, khơng âm  Một semaphore hỗ trợ hoạt động 26 hoạt động semaphore  wait: giảm giá trị semaphore Nếu giá trị = 0, hoạt động chặn lại đến giá trị trở thành dương (do hành động luồng khác) Khi giá trị trở thành dương, bị giảm hoạt động wait trở  post: tăng giá trị semaphore lên Nếu semaphore trước = luồng khác bị chặn hoạt động wait semaphore số luồng mở chặn hoạt động wait hoàn thành (khiến giá trị =0) 27 Thư viện, kiểu, hàm với semaphore   sem_t  sem_init  sem_destroy  sem_wait, sem_trywait  sem_post  sem_getvalue  Listing 4.12: job-queue3.c 28 4.3.5 Biến trạng thái    Biến trạng thái chế thứ ba giúp đồng hóa tiến trình thực điều kiện phức tạp Giả sử bạn viết hàm thread thực lặp vô hạn, bước lặp thực việc Tuy nhiên, việc lặp cần điều khiển cờ  cờ thiết lập, việc lặp tiếp tục  cờ không thiết lập, việc lặp tạm ngừng Listing 4.13 (spin-condvar.c): thực thi biến trạng thái đơn giản 29 4.4 GNU/Linux Thread Implemetation  Sự thực thi luồng POSIX GNU/Linux khác với nhiều HĐH dạng UNIX khác:     luồng thực thi tiến trình gọi pthread_create để tạo luồng mới, Linux tạo tiến trình để chạy luồng nhiên, tiến trình khơng giống tiến trình tạo fork: thay nhận copy, chia sẻ khơng gian địa tài nguyên Listing 4.15 (thread-pid.c): chương trình tạo luồng, luồng ban đầu luồng gọi hàm getpid, in process ID tương ứng quay vịng vơ hạn 30 4.5 Processes Vs Threads    Tất luồng chương trình phải chạy excutable Một tiến trình chạy excutable khác cách gọi hàm exec Một luồng sai sót gây hại cho luồng khác tiến trình chúng chia sẻ không gian nhớ ảo tài nguyên khác Một tiến trình sai sót khơng thể tiến trình có copy khơng gian nhớ chương trình Bộ nhớ copy cho tiến trình dễ gây tải hệ thống tạo luồng Tuy nhiên, việc copy xảy nhớ bị thay đổi 31 Processes Vs Threads (tiếp)   Các luồng nên dùng chương trình cần độ song song cao Các tiến trình nên dùng chương trình cần độ song song Việc chia sẻ liệu luồng quan trọng chúng chia sẻ nhớ (tuy nhiên cần cẩn thận để tránh trạng thái tranh đua) Việc chia sẻ liệu tiến trình cần có chế giao tiếp liên tiến trình (IPC, chương 5), nặng nề giảm ảnh hưởng lỗi đồng thời 32 ... thống lập lịch luồng để chạy Một luồng chạy lâu, hệ thống chuyển luồng nhanh Trên hệ thống đa xử lý, chí hệ thống lập lịch nhiều luồng chạy nghĩa đồng thời Gỡ lỗi chương trình đa luồng khó khơng... Listing 4.15 (thread-pid.c): chương trình tạo luồng, luồng ban đầu luồng gọi hàm getpid, in process ID tương ứng quay vịng vơ hạn 30 4.5 Processes Vs Threads    Tất luồng chương trình phải chạy... thứ tự thực luồng Ví dụ  Listing 4.1 (thread-create.c): tạo luồng in ký tự ‘x’; sau gọi pthread_create, luồng in ký tự ‘o’  kết chạy chương trình?  Lý do: Linux luân phiên lập lịch luồng 4.1.1

Ngày đăng: 10/05/2021, 13:39