Bài giảng Lập trình Windows - Chương 8: Lập trình đa luồng cung cấp cho người học các kiến thức: Giới thiệu lập trình đa luồng, lập trình luồng làm việc, lập trình luồng giao diện, một số lệnh liên quan, đồng bộ các luồng. Mời các bạn cùng tham khảo.
Chương Lập trình đa luồng 8.1 Giới thiệu lập trình đa luồng Khai thác tính đa nhiệm, chương trình lập trình thực nhiều phần việc đồng thời Gọi lập trình đa luồng (thread), gọi đa tuyến Luồng q trình thực đơn vị chương trình, độc lập với thực đơn vị khác chương trình Mỗi luồng thường gắn với thực hàm chương trình, ta gọi hàm hàm luồng Mỗi chương trình chạy ln có luồng ứng với thực hàm chương trình (WinMain), luồng khác tạo từ luồng luồng luồng luồng luồng luồng (main thread) thời gian 8.1 Giới thiệu lập trình đa luồng Mỗi luồng chương trình có mức độ ưu tiên thực hiện, tài nguyên thời gian máy dành cho luồng Ngoài luồng có tài nguyên stack, mức độ bảo mật, Minh họa chương trình đa luồng ứng với hàm: Chương trình Hàm Hàm Hàm Luồng Luồng Luồng (main thread) Luồng Luồng Có hai loại luồng: luồng làm việc (worker) luồng giao diện (user interface) Luồng làm việc chạy bên máy, luồng giao diện cung cấp tương tác với người dùng 8.2 Lập trình luồng làm việc Luồng làm việc lập trình hàm gọi hàm luồng, sau tạo luồng từ hàm này, gồm hai bước sau: Bước 1: Lập hàm xử lý luồng (hàm luồng), mẫu hàm khai báo sau: UINT tên_hàm ( LPVOID tham_số ); Trong tham số nhận liệu cho việc thực bên hàm luồng, truyền từ câu lệnh tạo luồng bước Bước 2: Tạo luồng thời điểm cần thiết CWinThread* AfxBeginThread( tên_hàm_luồng , dữ_liệu_truyền ); Có thể quy định tham số độ ưu tiên, độ lớn stack, tham số lệnh tạo luồng Mẫu đầy đủ sau: CWinThread* AfxBeginThread( AFX_THREADPROC pfnThreadProc, LPVOID pParam, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL ); Lệnh tạo luồng trả trỏ đối tượng luồng tạo tương ứng, kiểu lớp CWinThread Qua đối tượng tác động lên luồng chạy 8.3 Lập trình luồng giao diện MFC cung cấp lớp cho việc lập trình luồng kiểu giao diện, có tên CWinThread, lớp có phương thức ảo Run() để chạy ứng với luồng Chúng ta xây dựng lớp kế thừa CWinThread, viết đè hàm Run() để thực luồng theo mẫu sau, lớp phải có chế tạo động – DYNCREATE class tên_lớp_luồng : public CWinThread { public: void Run() { lập trình hàm chạy luồng } DECLARE_DYNCREATE() }; IMPLEMENT_DYNCREATE( tên_lớp_luồng , CWinThread ) Viết lệnh tạo luồng sử dụng lớp thời điểm mong muốn CWinThread AfxBeginThread( RUNTIME_CLASS( tên_lớp_luồng ) ); Ngồi viết đè phương thức khác để thực theo yêu cầu InitInsance(), ExitInstance(), OnIdle(), Luồng giao diện giống luồng ứng dụng 8.4 Một số lệnh liên quan Hàm kết thúc luồng void AfxEndThread( UINT nExitCode ); Một số thành viên lớp đối tượng CWinThread để quản lý luồng, CWinThread:: m_hThread : số hiệu định danh luồng, m_nThreadID : số luồng, m_pMainWnd : trỏ đối tượng cửa sổ ứng dụng, int GetThreadPriority(); lấy độ ưu tiên luồng, void SetThreadPriority( int k ); đặt độ ưu tiên luồng, DWORD SuspendThread(); tạm dừng thực luồng, DWORD ResumeThread(); tiếp tục chạy luồng, 8.5 Đồng luồng Khi luồng thực xử lý tài ngun (ví dụ liệu) dẫn đến xung đột, không quán gọi không đồng Minh họa không đồng luồng liệu data Thread1 Thread2 set A set B store data B A? inc by C use data change data inc by D change data use data store data use data B+C? A+D? use data thời gian 8.5 Đồng luồng Cách 1: Sử dụng phương pháp dựng cờ, lần luồng cần xử lý liệu phải chờ trạng thái cờ trạng thái tắt, bật trạng thái cờ để xử lý, xử lý xong tắt trạng thái cờ để luồng khác xử lý tiếp Minh họa đoạn chương trình sau: while (flag); //chờ giá trị cờ flag = 1; // truy xuất tài nguyên dùng chung // flag = 0; Cách 2: Dùng đối tượg khóa CSingleLock thực với phương thức: CSingleLock( CSyncObject *SyncOb, BOOL InitialState = FALSE); BOOL CSingleLock :: Lock( DWORD dwDelay=INFINITE); BOOL CSingleLock :: UnLock(); BOOL CSingleLock :: UnLock( LONG Count, LONG *Previous=NULL); Đối tượng đồng kiểu CSyncObject, lớp sở ảo cung cấp chế đồng luồng Các lớp kề thừa gồm CEvent, CMutex, CCriticalSection, CSemaphore 8.5 Đồng luồng Các bước thực đồng theo đối tượng trên: Bước 1: Tạo đối tượng đồng từ lớp CCriticalSection, CEvent, CMutex, CSemaphore dùng để điều khiển truy xuất tài nguyên Bước 2: Tạo đối tượng lớp CSingleLock sử dụng đối tượng đồng tạo bước Bước 3: Để chặn truy xuất tới tài nguyên gọi hàm Lock() đối tượng CSingleLock Bước 4: Thực truy xuất tài nguyên Bước 5: Gọi UnLock() để hủy bỏ chặn hàm Lock() ... thiệu lập trình đa luồng Khai thác tính đa nhiệm, chương trình lập trình thực nhiều phần việc đồng thời Gọi lập trình đa luồng (thread), gọi đa tuyến Luồng trình thực đơn vị chương trình, độc lập. .. họa chương trình đa luồng ứng với hàm: Chương trình Hàm Hàm Hàm Luồng Luồng Luồng (main thread) Luồng Luồng Có hai loại luồng: luồng làm việc (worker) luồng giao diện (user interface) Luồng. .. khác chương trình Mỗi luồng thường gắn với thực hàm chương trình, ta gọi hàm hàm luồng Mỗi chương trình chạy ln có luồng ứng với thực hàm chương trình (WinMain), luồng khác tạo từ luồng luồng