欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++創(chuàng)建多線程的方法總結(jié)

 更新時間:2024年01月28日 10:24:15   作者:Thomas_Lbw  
下個迭代有個任務(wù)很有趣,用大量的線程去訪問一個接口,直至其崩潰為止,這就需要多線程的知識,這也不是什么難事,本文總結(jié)一下C++中的多線程方法std、boost、pthread、windows?api,感興趣的朋友可以參考下

一、多線程預(yù)備知識

多線程本質(zhì)是將程序的運(yùn)行拆分為部分,每個線程都有自己的執(zhí)行上下文,包括它的程序計(jì)數(shù)器,寄存器和棧,并且它們獨(dú)立地執(zhí)行,互不干擾。我們必須要明確的是多線程的實(shí)現(xiàn)依賴硬件條件:多線程需要多核處理器。多核處理器可以同時執(zhí)行多個線程,因此多線程可以利用多核處理器的多個內(nèi)核來實(shí)現(xiàn)更快的處理速度和更高的性能。通過使用多核處理器,可以把多個線程并行執(zhí)行,從而實(shí)現(xiàn)更高的性能和更快的處理速度。

比如說,在圖像處理應(yīng)用中,如果使用多核處理器,可以把圖像處理任務(wù)分成多個獨(dú)立的部分,并使用多個線程分別執(zhí)行每個部分。每例如,線程 1 可以處理圖像的顏色校正,線程 2 可以處理圖像的縮放,線程 3 可以處理圖像的旋轉(zhuǎn)等。由于每個線程都可以同時執(zhí)行,因此處理速度比單線程處理要快得多。需要注意的是,在這種情況下,還需要考慮線程間的同步和通信,以確保線程之間的數(shù)據(jù)一致性。

二、C++11 std::thread 

2.1 創(chuàng)建線程

#include <iostream>
#include <thread>
 
void foo()
{
    std::cout << "Hello from thread" << std::endl;
}
 
int main()
{
    std::thread t1(foo);
    t1.join();
 
    return 0;
}

在上面的代碼中,通過 std::thread t1(foo) 創(chuàng)建了一個新線程,并在新線程中執(zhí)行了函數(shù) foo。 

2.2 線程管理

#include <iostream>
#include <thread>
 
void foo()
{
    std::cout << "Hello from thread" << std::endl;
}
 
int main()
{
    std::thread t1(foo);
    t1.join();
    t1.detach();
 
    return 0;
}

在上面的代碼中,通過調(diào)用 t1.join() 可以等待線程 t1 結(jié)束,并通過調(diào)用 t1.detach() 可以分離線程 t1,使線程在后臺運(yùn)行。 

std::thread::detach() 方法是分離線程的方法,通過調(diào)用 detach() 方法,可以讓線程在后臺獨(dú)立運(yùn)行,不需要等待線程結(jié)束即可返回。與調(diào)用 join() 方法不同,分離的線程不受父線程的控制,因此如果父線程結(jié)束,分離的線程不會因此結(jié)束。請注意,分離的線程一旦開始執(zhí)行,它將獨(dú)立運(yùn)行,不受任何控制,因此不能在父線程中等待它的結(jié)束或者通過其他方式獲取其結(jié)果。如果需要等待線程結(jié)束,請使用 join() 方法。

分離線程的主要作用是讓線程在后臺獨(dú)立運(yùn)行,不需要等待線程結(jié)束即可返回。這樣可以在不需要等待線程結(jié)束的情況下,在父線程中執(zhí)行其他任務(wù),從而提高程序的效率。

2.3 傳遞參數(shù)

#include <iostream>
#include <thread>
 
void foo(int x)
{
    std::cout << "Hello from thread, x = " << x << std::endl;
}
 
int main()
{
    std::thread t1(foo, 10);
    t1.join();
 
    return 0;
}

在上面的代碼中,通過在創(chuàng)建線程時傳遞參數(shù) 10,并在函數(shù) foo 中讀取參數(shù),實(shí)現(xiàn)了在線程中傳遞參數(shù)的功能。

2.4 線程間通信 

2.4.1 使用共享變量和互斥量(互斥鎖):

#include <iostream>
#include <thread>
#include <mutex>
 
int g_num = 0;
std::mutex g_num_mutex;
 
void print_num() {
    while (true) {
        g_num_mutex.lock();
        if (g_num >= 100) {
            g_num_mutex.unlock();
            break;
        }
        std::cout << "Thread " << std::this_thread::get_id() << ": " << g_num++ << std::endl;
        g_num_mutex.unlock();
    }
}
 
int main() {
    std::thread t1(print_num);
    std::thread t2(print_num);
 
    t1.join();
    t2.join();
 
    return 0;
}

我們定義了一個全局變量g_num,兩個線程分別運(yùn)行print_num函數(shù)。print_num函數(shù)不斷地對g_num變量進(jìn)行讀寫操作,并使用互斥量g_num_mutex對該變量進(jìn)行加鎖。這樣可以確保在每次讀寫操作時,不會有其他線程訪問g_num變量。如果g_num的值已經(jīng)大于等于100,則表示線程退出。最后主線程調(diào)用join函數(shù),等待其他線程退出。

2.4.2 使用共享內(nèi)存

#include <iostream>
#include <thread>
#include <string>
 
using namespace std;
 
string message;
 
void write_message()
{
    message = "Hello World";
}
 
void read_message()
{
    cout << message << endl;
}
 
int main()
{
    thread t1(write_message);
    thread t2(read_message);
 
    t1.join();
    t2.join();
 
    return 0;
}

2.5 其他線程相關(guān)信息

  • std::thread::hardware_concurrency():返回當(dāng)前系統(tǒng)支持的最大線程數(shù)。
  • std::thread::native_handle():返回線程的原生句柄,在不同的平臺中可能不同。
  • std::thread::joinable():判斷線程是否可以被 join,如果線程已經(jīng)結(jié)束或者被分離,則返回 false。
  • std::thread::join():等待線程結(jié)束,直到線程結(jié)束才返回。
  • std::thread::detach():分離線程,使線程可以在后臺運(yùn)行,并且不需要等待其結(jié)束。
  • std::thread::get_id() :返回線程ID。

三、boost多線程庫

官方文檔:

Chapter 38. Thread 4.8.0 - 1.73.0

Boost 庫中的 boost::thread 類可以方便地創(chuàng)建和管理多線程。以下是一個使用 Boost 庫中的 boost::thread 類創(chuàng)建多線程的簡單示例:

#include <iostream>
#include <boost/thread.hpp>
 
void worker_thread()
{
    std::cout << "Worker thread is running" << std::endl;
}
 
int main()
{
    boost::thread worker(worker_thread);
    std::cout << "Main thread is running" << std::endl;
    worker.join();
 
    return 0;
}

四、POSIX線程(Linux&Unix) 

C++ POSIX 線程(pthread)庫可以幫助您在 C++ 中創(chuàng)建和管理多線程。下面是一個創(chuàng)建和啟動一個新線程的示例代碼:

#include <pthread.h>
#include <iostream>
 
void *thread_func(void *arg)
{
    std::cout << "Thread started with argument: " << *((int *)arg) << std::endl;
    return NULL;
}
 
int main()
{
    pthread_t thread_id;
    int arg = 42;
 
    // 創(chuàng)建新線程
    int result = pthread_create(&thread_id, NULL, thread_func, &arg);
    if (result != 0) {
        std::cerr << "Error: pthread_create() failed" << std::endl;
        return 1;
    }
 
    // 等待線程結(jié)束
    result = pthread_join(thread_id, NULL);
    if (result != 0) {
        std::cerr << "Error: pthread_join() failed" << std::endl;
        return 1;
    }
 
    return 0;
}

這段代碼中,pthread_create 函數(shù)用于創(chuàng)建一個新線程,并啟動它。第一個參數(shù)是一個指向線程 ID 的指針,第二個參數(shù)指定了線程的屬性,通常為 NULL,第三個參數(shù)是線程函數(shù)的地址,最后一個參數(shù)是傳遞給線程函數(shù)的參數(shù)。

pthread_join 函數(shù)等待線程結(jié)束,第一個參數(shù)是線程 ID,第二個參數(shù)是接收線程返回值的指針,通常為 NULL。

五、 Windows線程庫

5.1 線程使用

下面是使用Windows API創(chuàng)建線程并打印數(shù)字并獲取重要的線程信息的代碼示例:

#include <iostream>
#include <Windows.h>
 
DWORD WINAPI ThreadFunction(LPVOID lpParam)
{
    // 獲取當(dāng)前線程ID
    DWORD threadId = GetCurrentThreadId();
    std::cout << "Thread ID: " << threadId << std::endl;
 
    // 獲取線程傳入的參數(shù)
    int threadParam = *(int*)lpParam;
    for (int i = 0; i < threadParam; i++)
    {
        std::cout << i << std::endl;
    }
    return 0;
}
 
int main()
{
    int num = 10;
 
    // 創(chuàng)建線程
    HANDLE hThread = CreateThread(NULL, 0, ThreadFunction, &num, 0, NULL);
 
    // 等待線程結(jié)束
    WaitForSingleObject(hThread, INFINITE);
 
    // 關(guān)閉線程句柄
    CloseHandle(hThread);
 
    return 0;
}

5.2 線程通信

在 Windows API 中,可以使用 CreateThread 函數(shù)創(chuàng)建線程,以下是通過共享變量實(shí)現(xiàn)線程間通信的代碼示例:

#include <Windows.h>
#include <iostream>
 
DWORD WINAPI ThreadFunction1(LPVOID lpParam)
{
    int* sharedVariable = (int*)lpParam;
    while (true)
    {
        if (*sharedVariable == 0)
        {
            std::cout << "Thread 1: sharedVariable = " << *sharedVariable << std::endl;
            *sharedVariable = 1;
        }
    }
    return 0;
}
 
DWORD WINAPI ThreadFunction2(LPVOID lpParam)
{
    int* sharedVariable = (int*)lpParam;
    while (true)
    {
        if (*sharedVariable == 1)
        {
            std::cout << "Thread 2: sharedVariable = " << *sharedVariable << std::endl;
            *sharedVariable = 0;
        }
    }
    return 0;
}
 
int main()
{
    int sharedVariable = 0;
    HANDLE hThread1 = CreateThread(NULL, 0, ThreadFunction1, &sharedVariable, 0, NULL);
    HANDLE hThread2 = CreateThread(NULL, 0, ThreadFunction2, &sharedVariable, 0, NULL);
    WaitForMultipleObjects(2, &hThread1, TRUE, INFINITE);
    CloseHandle(hThread1);
    CloseHandle(hThread2);
    return 0;
}

在主函數(shù)中,我們調(diào)用了 CreateThread 函數(shù)創(chuàng)建了兩個線程,將共享變量 sharedVariable 的地址作為參數(shù)傳入。線程 1 和線程 2 都通過判斷共享變量的值來實(shí)現(xiàn)通信,它們每當(dāng)共享變量的值變化時都會輸出當(dāng)前的值。  

在這個例子中,WaitForMultipleObjects函數(shù)將等待兩個線程hThread1和hThread2完成,并且要求等待所有事件對象完成,因此參數(shù)bWaitAll的值為TRUE。并且dwMilliseconds的值為INFINITE,所以等待時間是無限的。

以上就是C++創(chuàng)建多線程的方法總結(jié)的詳細(xì)內(nèi)容,更多關(guān)于C++創(chuàng)建多線程的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Qt數(shù)據(jù)庫應(yīng)用之實(shí)現(xiàn)文件編碼格式識別

    Qt數(shù)據(jù)庫應(yīng)用之實(shí)現(xiàn)文件編碼格式識別

    在做數(shù)據(jù)導(dǎo)入導(dǎo)出的過程中,如果應(yīng)用場景多了,相信各位都會遇到一個問題就是文件編碼的問題。本文將用Qt實(shí)現(xiàn)文件編碼格式識別,感興趣的可以了解一下
    2022-06-06
  • 線段樹詳解以及C++實(shí)現(xiàn)代碼

    線段樹詳解以及C++實(shí)現(xiàn)代碼

    線段樹在一些acm題目中經(jīng)常見到,這種數(shù)據(jù)結(jié)構(gòu)主要應(yīng)用在計(jì)算幾何和地理信息系統(tǒng)中,這篇文章主要給大家介紹了關(guān)于線段樹以及C++實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • C++11中多線程編程-std::async的深入講解

    C++11中多線程編程-std::async的深入講解

    這篇文章主要給大家介紹了關(guān)于C++11中多線程編程-std::async的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • C語言實(shí)現(xiàn)棧及棧的詳解

    C語言實(shí)現(xiàn)棧及棧的詳解

    這篇文章主要介紹了C語言實(shí)現(xiàn)棧及棧的詳解,一種特殊的線性表,其只允許在固定的一端進(jìn)行插入和刪除元素操作,進(jìn)行數(shù)據(jù)插入和刪除操作的一端稱為棧頂,另一端稱為棧底,需要的朋友可以參考下
    2023-07-07
  • C++小練習(xí)之高性能實(shí)現(xiàn)字符串分割

    C++小練習(xí)之高性能實(shí)現(xiàn)字符串分割

    字符串分割是日常工作中比較常見的基礎(chǔ)函數(shù),通常大家會使用現(xiàn)成的基礎(chǔ)庫,基礎(chǔ)庫的性能是否是最佳的,本文主要和大家探討一下如何最大限度的提升字符串分割的性能,希望對大家有所幫助
    2023-10-10
  • VSCode之CMake使用小結(jié)

    VSCode之CMake使用小結(jié)

    本文主要介紹了VSCode之CMake使用小結(jié),文中通過圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-03-03
  • Qt使用隨機(jī)驗(yàn)證碼的實(shí)現(xiàn)示例

    Qt使用隨機(jī)驗(yàn)證碼的實(shí)現(xiàn)示例

    有時候在登錄界面需要驗(yàn)證碼功能,這樣能夠防止被惡意程序攻擊,本文主要介紹了Qt使用隨機(jī)驗(yàn)證碼的實(shí)現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • C語言中雙向鏈表和雙向循環(huán)鏈表詳解

    C語言中雙向鏈表和雙向循環(huán)鏈表詳解

    這篇文章主要介紹了C語言中雙向鏈表和雙向循環(huán)鏈表詳解的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • 深入解析最長公共子串

    深入解析最長公共子串

    本篇文章是對最長公共子串進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C++ primer基礎(chǔ)之容器insert

    C++ primer基礎(chǔ)之容器insert

    這篇文章主要介紹了C++ primer基礎(chǔ)之容器insert的相關(guān)資料,需要的朋友可以參考下
    2017-02-02

最新評論