close up photo of programming of codes

codecungnhau.com

Một trang web về kỹ thuật lập trình

C++11 Multithreading – P.1: Ba cách để khởi chạy một Thread

Trong các phiên bản chuẩn trước đây của C++ chỉ hộ trợ lập trình đơn luồng. Nhưng bắt đầu từ phiên bản C++ 11, chúng ta đã được giới thiệu về một gói thư viện mới là thread. Gói thư viện này hỗ trợ cho việc lập trình đa luồng (C++ Multithreading).

Các trình biên dịch yêu cầu:

Linux: gcc 4.8.1 (Complete Concurrency support)
==> Cách để compile trên Linux: g++ sample.cpp -pthread -o sample
Windows: Visual Studio 2012 and MingW

Khởi tạo Thread trong C++

Trong mỗi ứng dụng C++, có một luồng chính mặc định, tức là hàm main(). Trong C++ 11, chúng ta có thể tạo các luồng bổ sung bằng cách tạo các đối tượng của lớp std::thread. Mỗi đối tượng std::thread có thể được liên kết với một luồng.

Header file:

#include <thread>

Chúng ta có thể đưa vào một callback cho đối tượng std::thread. Nó sẽ được thực thi khi luồng mới này bắt đầu. Những callback có thể là một con trỏ hàm (Function Pointer), các đối tường hàm (Function Objects), hàm lambda.

Một đối tượng Thread có thể khởi tạo như sau:

td::thread thObj(<CALLBACK>);

Thread mới sẽ bắt đầu ngay sau khi tạo đối tượng mới và sẽ thực hiện một lời gọi callback được truyền song song với luồng đã khởi động nó. Hơn nữa, bất kỳ luồng nào cũng có thể đợi luồng khác thoát ra bằng cách gọi hàm join() trên đối tượng của luồng đó.

Hãy xem xét một ví dụ trong đó luồng chính sẽ tạo ra một luồng riêng. Sau khi tạo luồng mới này, luồng chính sẽ in một số dữ liệu trên console và sau đó đợi luồng mới được tạo để thoát. Hãy thực hiện việc này bằng ba cơ chế callback khác nhau.

Khởi tạo bằng Function Pointer

#include <iostream>
#include <thread>
 
void thread_function()
{
    for(int i = 0; i < 10000; i++)
        std::cout<<"thread function Executing"<<std::endl;
}
 
int main()  
{
    
    std::thread threadObj(thread_function);
    for(int i = 0; i < 10000; i++)
        std::cout<<"Display From MainThread"<<std::endl;
    threadObj.join();    
    std::cout<<"Exit of Main function"<<std::endl;
    return 0;
}

Khởi tạo bằng Function Objects

#include <iostream>
#include <thread>
class DisplayThread
{
public:
    void operator()()     
    {
        for(int i = 0; i < 10000; i++)
            std::cout<<"Display Thread Executing"<<std::endl;
    }
};
 
int main()  
{
    std::thread threadObj( (DisplayThread()) );
    for(int i = 0; i < 10000; i++)
        std::cout<<"Display From Main Thread "<<std::endl;
    std::cout<<"Waiting For Thread to complete"<<std::endl;
    threadObj.join();
    std::cout<<"Exiting from Main Thread"<<std::endl;
    return 0;
}

Khởi tạo bằng Lambda Function

#include <iostream>
#include <thread>
int main()  
{
    std::thread threadObj([]{
            for(int i = 0; i < 10000; i++)
                std::cout<<"Display Thread Executing"<<std::endl;
            });
            
    for(int i = 0; i < 10000; i++)
        std::cout<<"Display From Main Thread"<<std::endl;
        
    threadObj.join();
    std::cout<<"Exiting from Main Thread"<<std::endl;
    return 0;
}

Phân biệt giữa các luồng

Mỗi đối tượng std::thread đều có ID riêng. Ta có thể tìm ra nó bằng cách sử dụng hàm get_id() để lấy được ID tương ứng

std::thread::get_id()

Hoặc, lấy ID từ chính luồng đang chạy

std::this_thread::get_id()

Nếu đối tượng std::thread không có một một thread được liên kết, get_id() sẽ trả về đối tượng id mặc định. Đối tượng này có thể so sánh được, cũng như in kết quả ra màn hình.

#include <iostream>
#include <thread>
void thread_function()
{
    std::cout<<"Inside Thread :: ID  = "<<std::this_thread::get_id()<<std::endl;    
}
int main()  
{
    std::thread threadObj1(thread_function);
    std::thread threadObj2(thread_function);
 
    if(threadObj1.get_id() != threadObj2.get_id())
        std::cout<<"Both Threads have different IDs"<<std::endl;
 
        std::cout<<"From Main Thread :: ID of Thread 1 = "<<threadObj1.get_id()<<std::endl;    
    std::cout<<"From Main Thread :: ID of Thread 2 = "<<threadObj2.get_id()<<std::endl;    
 
    threadObj1.join();    
    threadObj2.join();    
    return 0;
}

Đã đăng vào

trong

,

bởi

Bình luận

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *