Lập trình UD Desktop_10 - Thread

Bài trước: Lập trình UD Desktop_09 - ContextMenu NotifyIcon
-----

2.20       Thread


Nhân tiện, ôn lại một chút kiến thức của môn Hệ điều hành. Để ý là các môn học Nhập môn ngành CNTT, Kiến trúc máy tính, Hệ điều hành, Kĩ thuật lập trình, Cấu trúc dữ liệu và thuật toán, Mạng máy tính, Lập trình hướng đối tượng và các môn học khác, là những nền tảng quan trọng, giúp người học hiểu về chính cái máy tính. Mình có hiểu về máy tính thì mới thích, mới có thể điều khiển được nó.

– Khi lấy một phần mềm từ Internet về máy (ví dụ Microsoft Office, Visual Studio Code) thì phần mềm đó tồn tại dưới dạng một tập tin

– Sau khi cài đặt, thì phần mềm đó tồn tại dưới dạng một chương trình được lưu trên đĩa cứng

– Khi chạy chương trình đó trên máy tính, thì sẽ tạo ra một tiến trình (process)

– Trong một tiến trình có thể có nhiều chương trình con đang chạy gọi là tiểu trình (hay luồng) (thread)

– Cùng một lúc máy tính có thể chạy nhiều tiến trình (hay nhiều chương trình)

Vậy, tiến trình là một chương trình đang được thực thi, trong một tiến trình có thể có nhiều “tiến trình con” đang chạy cùng lúc gọi là các tiểu trình.

Một tiến trình thường gồm:

– Định danh: để phân biệt với các tiến trình khác

– Trạng thái: thể hiện trạng thái hiện thời

– Độ ưu tiên: xác định độ ưu tiên của tiến trình

– Giá trị của thanh ghi PC: địa chỉ của lệnh kế tiếp sẽ được thực thi.

– Các địa chỉ tham chiếu: tới vùng mã, vùng dữ liệu

– Thông tin trạng thái: thông tin trong các thanh ghi

– Thông tin trạng thái nhập/xuất

– Các thông tin thống kê (accounting information)

– Các thông tin trên được lưu trong PCB (process control block)

Một tiểu trình:

– Là đơn vị xử lý cơ bản trong hệ thống

– Xử lý tuần tự đoạn mã của nó

– Sở hữu một con trỏ lệnh, một tập các thanh ghi và một vùng nhớ stack riêng

– Cũng chia sẻ thời gian xử lý của processor như các tiến trình

– Một tiến trình có thể có nhiều tiểu trình 

Xem hai hình sau cho dễ hiểu,



và,



Hiểu lý thuyết rồi giờ sẽ áp dụng vào lập trình, xem clip sau,

Sau bài học này bạn sẽ:

– Hiểu được khái niệm thread, deadlock, main thread

– Tạo được nhiều thread trong winform

Trong một dự án, vào tập tin Program.cs để xem luồng (thread) chính, một chương trình luôn có một luồng chính,

static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }

Để tạo thêm luồng mới cần làm một số việc sau:

– Khai báo đầu vào của luồng, ví dụ đầu vào của luồng chính là hàm demXuoi,

ThreadStart ts = new ThreadStart(demXuoi);

– Tạo ra một luồng, dựa trên đầu vào đã có,

Thread thr = new Thread(ts);

– Khởi chạy luồng vừa được tạo ra,

thr.Start();

Để các luồng có thể dùng chung tài nguyên trên form (control, hoặc biến) của nhau có thể thiết lập việc kiểm tra tài nguyền dùng chung là fasle, tuy nhiên cách này dễ làm chương trình bị treo,         

Control.CheckForIllegalCrossThreadCalls = false;

Học thêm về delegate, lambda expression, anonymous function ở đây :

Lambda expression là cách ngắn gọn để viết một anonymous function. Anonymous function là một hàm không có tên. Hàm không có tên này được dùng để gán cho một biến, hoặc được xem như là một biến.

Cú pháp của lambda expression là:

( input-parameters ) => { statement }

Ví dụ, từ hai hàm sau,

        private void button1_Click(object sender, EventArgs e)
        {
            ThreadStart ts1 = new ThreadStart(demXuoi);
            Thread thr1 = new Thread(ts1);
            thr1.Start();
        }

        void demXuoi()
        {
            for(int i = 0; i < Convert.ToInt32(textBox1.Text); i++)
            {
                label1.Text = i.ToString();
            }
        }

Sử dụng kiểu viết Lambda expression để gộp lại như sau,

        private void button1_Click(object sender, EventArgs e)
        {
            new Thread(
                () =>
                    {
                        for (int i = 0; i < Convert.ToInt32(textBox1.Text); i++)
                        {
                            label1.Text = i.ToString();
                        }
                    }
                ).Start();
        }

Trong đó,

– () là một anonymous function, không có tham số truyền vào

– => là chỉ dẫn, có nghĩa là “sau đây là phần định nghĩa của hàm”

– {} nội dung của hàm

Lab 17. Tạo chương trình đếm số

[Tạo giao diện như sau]



[Yêu cầu chức năng]

– Cho người dùng nhập một số, sau đó bấm vào nút Luồng 1 – Đếm xuôi và Luồng 2 – Đếm ngược, quá trình đếm số sẽ được hiển thị ở hai label ĐẾM XUÔI và ĐẾM NGƯỢC.

– Viết xử lý cho nút [Luồng 1 – Đếm xuôi] bằng kiểu thông thường

– Viết xử lý cho nút [Luồng 2 – Đếm ngược] có sử dụng Lambda expression

[Giao diện khi đang chạy]


-----
Tiếp theo: Lập trình UD Desktop_11 - Timer ProgressBar NumericUpDown Process DateTimePicker LinQ
Xem thêm: Danh sách các bài học