最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++實(shí)現(xiàn)多線程編程的方式匯總

 更新時(shí)間:2026年07月26日 14:44:21   作者:胖大和尚  
搞不懂C++多線程技術(shù)怎么選,本文幫你理清std::thread、pthread、OpenMP、MPI等核心技術(shù)的區(qū)別和適用場景,讓你不再糾結(jié),無論是普通應(yīng)用開發(fā)、科學(xué)計(jì)算還是GUI編程,都能找到最適合你的并行方案

在 C++ 中,實(shí)現(xiàn)多線程編程的方法有很多,從底層到高層大致可以分為以下幾類。

方式標(biāo)準(zhǔn)是否推薦適用場景
POSIX Threads (pthread)POSIX????Linux/Unix 系統(tǒng)開發(fā)
std::threadC++11?????現(xiàn)代 C++ 首選
std::asyncC++11???簡單異步任務(wù)
OpenMP編譯器擴(kuò)展?????科學(xué)計(jì)算、循環(huán)并行
Intel TBB / oneTBB第三方庫????任務(wù)并行
Boost.ThreadBoost???老項(xiàng)目兼容
Qt QThreadQt????Qt GUI 程序
MPI第三方庫?多進(jìn)程,不屬于線程庫

注意最后一項(xiàng) MPI 不是線程庫,而是進(jìn)程并行庫。

1. std::thread(現(xiàn)代 C++ 首選)

C++11 開始標(biāo)準(zhǔn)提供。

#include <thread>
#include <iostream>

void work(int id)
{
    std::cout << id << std::endl;
}

int main()
{
    std::thread t1(work, 1);
    std::thread t2(work, 2);

    t1.join();
    t2.join();
}

優(yōu)點(diǎn):

  • 跨平臺
  • STL 風(fēng)格
  • 推薦新項(xiàng)目使用

配套還有:

std::mutex
std::lock_guard
std::unique_lock
std::condition_variable
std::atomic
std::future

2. pthread(Linux 最經(jīng)典)

這是 Linux 系統(tǒng)接口。

#include <pthread.h>

void* func(void*)
{
    return nullptr;
}

int main()
{
    pthread_t tid;

    pthread_create(&tid, nullptr, func, nullptr);

    pthread_join(tid, nullptr);
}

優(yōu)點(diǎn):

  • Linux 下功能最完整
  • 很多老項(xiàng)目都在用

缺點(diǎn):

  • C 風(fēng)格 API
  • 使用起來比較繁瑣

很多 std::thread 的實(shí)現(xiàn)底層實(shí)際上會(huì)調(diào)用 pthread(在 Linux 上)。

3. std::async

適合執(zhí)行一個(gè)異步任務(wù)。

auto result = std::async(std::launch::async,
                         []()
                         {
                             return 100;
                         });

std::cout << result.get();

不需要自己創(chuàng)建線程。

4. OpenMP(科學(xué)計(jì)算最常見)

例如:

#pragma omp parallel for
for(int i=0;i<N;i++)
{
    a[i]+=b[i];
}

編譯:

g++ -fopenmp

OpenMP 特點(diǎn):

  • 幾乎不用管理線程
  • 編譯器自動(dòng)完成

VASP、LAMMPS、OpenFOAM 都大量使用。

例如:

#pragma omp parallel
{
    // 多線程
}

5. Intel TBB(oneTBB)

Intel 的任務(wù)調(diào)度庫。

例如:

tbb::parallel_for(
    0,
    N,
    [&](int i)
    {
        ...
    });

比 OpenMP 更靈活。

很多工業(yè)軟件使用:

  • OpenCV
  • oneAPI

6. Boost.Thread

現(xiàn)代 C++ 出現(xiàn)以前最流行。

boost::thread t(func);

現(xiàn)在基本被:

std::thread

替代。

7. Qt 的 QThread

Qt GUI 開發(fā)必備。

例如:

class Worker : public QThread
{
    void run() override
    {
        ...
    }
};

主要解決:

  • GUI 不阻塞
  • 信號槽

8. 線程池(Thread Pool)

嚴(yán)格來說不是一種線程 API,而是一種編程模式。

例如:

ThreadPool pool(8);

pool.enqueue(task1);
pool.enqueue(task2);

優(yōu)點(diǎn):

  • 避免頻繁創(chuàng)建線程
  • 性能最好

很多服務(wù)器都采用這種方式。

C++23 標(biāo)準(zhǔn)沒有正式線程池,很多項(xiàng)目使用:

  • BS::thread_pool
  • oneTBB
  • folly
  • Boost.Asio

9. MPI(容易和線程混淆)

MPI:

MPI_Init(...);

MPI_Comm_rank(...);

MPI_Send(...);

它創(chuàng)建的是:

Process0
Process1
Process2

不是:

Thread1
Thread2

所以:

MPI 是多進(jìn)程,不是多線程。

在 HPC 中通常是混合并行

像 VASP、GROMACS 等 HPC 軟件通常會(huì)組合使用多種技術(shù):

多個(gè)節(jié)點(diǎn)
    │
    ▼
 MPI(多進(jìn)程)
    │
    ▼
OpenMP(每個(gè)進(jìn)程多個(gè)線程)
    │
    ▼
CUDA/HIP(GPU 并行)

例如:

Node1
 ├── MPI Rank0
 │      ├── Thread0
 │      ├── Thread1
 │      └── Thread2
 └── MPI Rank1
        ├── Thread0
        ├── Thread1
        └── GPU0

因此,一個(gè) VASP 作業(yè)中通常會(huì)同時(shí)用到 MPI + OpenMP + CUDA/HIP,分別負(fù)責(zé)不同層次的并行。

實(shí)際工作中的常見選擇

如果按行業(yè)來看,大致可以這樣歸納:

  • 普通 C++ 應(yīng)用開發(fā)std::thread 是首選,Linux 老項(xiàng)目中 pthread 仍然很多。
  • 科學(xué)計(jì)算 / HPC:OpenMP + MPI 是主流,GPU 場景再結(jié)合 CUDA/HIP。
  • GUI 開發(fā)(Qt):通常使用 QThread。
  • 高性能服務(wù)器:更多使用線程池、任務(wù)調(diào)度庫(如 oneTBB、Boost.Asio、folly 等),而不是頻繁創(chuàng)建和銷毀線程。

這張表有一定誤導(dǎo)性。MPI 和 OpenMP 并不是“見得少”,而是它們主要集中在科學(xué)計(jì)算和 HPC 領(lǐng)域;在通用 C++ 應(yīng)用、服務(wù)端和 GUI 開發(fā)中相對少見。

另外,現(xiàn)代 C++ 新項(xiàng)目通常優(yōu)先使用 std::thread,并不是普遍優(yōu)先使用 pthread。pthread 更多見于 Linux 系統(tǒng)軟件、底層運(yùn)行時(shí)和歷史項(xiàng)目。

先區(qū)分三種并行模型

技術(shù)并行單位內(nèi)存模型典型范圍
pthread / std::thread線程共享內(nèi)存單個(gè)進(jìn)程、單臺機(jī)器
OpenMP線程共享內(nèi)存單進(jìn)程、單個(gè)計(jì)算節(jié)點(diǎn)
MPI進(jìn)程分布式內(nèi)存、消息傳遞單節(jié)點(diǎn)或多個(gè)計(jì)算節(jié)點(diǎn)

MPI 不是線程庫。它主要解決:

節(jié)點(diǎn) A 的進(jìn)程如何和節(jié)點(diǎn) B 的進(jìn)程交換數(shù)據(jù)

OpenMP 和線程庫主要解決:

同一進(jìn)程內(nèi)多個(gè) CPU 核心如何共享數(shù)據(jù)并行計(jì)算

為什么通用 C++ 項(xiàng)目中 MPI 不常見

MPI 主要面向多進(jìn)程、分布式內(nèi)存計(jì)算。例如超算中:

計(jì)算節(jié)點(diǎn) 0:MPI rank 0~63
計(jì)算節(jié)點(diǎn) 1:MPI rank 64~127
計(jì)算節(jié)點(diǎn) 2:MPI rank 128~191

進(jìn)程之間通過消息通信:

MPI_Send(...);
MPI_Recv(...);
MPI_Allreduce(...);

它特別適合:

  • VASP、LAMMPS、GROMACS 等科學(xué)計(jì)算;
  • 流體、氣象、量子化學(xué)計(jì)算;
  • 大規(guī)模矩陣和網(wǎng)格計(jì)算;
  • 跨多個(gè)服務(wù)器或超算節(jié)點(diǎn)運(yùn)行。

普通桌面程序、Web 服務(wù)或 GUI 程序通常不需要同時(shí)使用幾十臺服務(wù)器做一次緊密耦合計(jì)算,因此很少使用 MPI。

另外,MPI 程序通常需要專門啟動(dòng):

mpirun -np 64 ./program

它的進(jìn)程部署、通信、負(fù)載均衡和故障處理也比普通線程復(fù)雜。

所以不是 MPI 不成熟,而是它解決的問題與普通多線程不同。在 HPC 中,MPI 非常常見,甚至可以說是基礎(chǔ)設(shè)施。

為什么通用 C++ 中 OpenMP 看起來也不多

OpenMP 最擅長的是規(guī)則循環(huán)并行:

#pragma omp parallel for
for (int i = 0; i < n; ++i) {
    c[i] = a[i] + b[i];
}

這類代碼在科學(xué)計(jì)算中很多,因此 OpenMP 非常合適。

但通用 C++ 程序的并發(fā)任務(wù)通常不是規(guī)則循環(huán),例如:

  • 網(wǎng)絡(luò)連接處理;
  • 后臺任務(wù)隊(duì)列;
  • 文件異步讀寫;
  • GUI 后臺計(jì)算;
  • 長生命周期工作線程;
  • 生產(chǎn)者/消費(fèi)者;
  • 線程池;
  • 復(fù)雜任務(wù)依賴。

這些場景通常需要顯式控制:

創(chuàng)建線程
等待線程
條件變量
互斥鎖
任務(wù)隊(duì)列
線程生命周期
異常和退出

std::threadstd::jthread、線程池或異步框架更適合這些需求。

OpenMP 的優(yōu)勢是快速表達(dá)“把這一段計(jì)算并行化”,而不是構(gòu)建完整的并發(fā)軟件架構(gòu)。

為什么有些 C++ 項(xiàng)目使用 pthread

pthread 是 POSIX 線程接口,長期以來是 Linux/Unix 的底層線程標(biāo)準(zhǔn):

pthread_create(...);
pthread_join(...);
pthread_mutex_lock(...);

它常見的原因主要有以下幾個(gè)。

1. 歷史原因

C++11 以前,標(biāo)準(zhǔn) C++ 沒有正式的線程庫。Linux C/C++ 項(xiàng)目普遍使用 pthread。許多成熟項(xiàng)目延續(xù)了原有設(shè)計(jì)。

2. 同時(shí)支持 C 和 C++

pthread 是 C 接口,可以被 C 和 C++ 使用。操作系統(tǒng)、數(shù)據(jù)庫和底層庫經(jīng)常包含大量 C 代碼。

3. Linux 平臺的底層控制

pthread 提供一些平臺相關(guān)能力,例如:

pthread_setaffinity_np
pthread_setschedparam
pthread_setname_np

可用于:

  • CPU 親和性;
  • 實(shí)時(shí)調(diào)度策略;
  • 線程棧大??;
  • 線程名稱;
  • NUMA 和性能調(diào)優(yōu)。

雖然 C++ 標(biāo)準(zhǔn)線程可以通過 native_handle() 獲取底層 pthread,但底層系統(tǒng)軟件有時(shí)會(huì)直接使用 pthread。

4. 很多高級線程庫最終建立在 pthread 上

在 Linux 中:

std::thread
OpenMP runtime
oneTBB
各種線程池
        ↓
通常最終使用 pthread/clone 創(chuàng)建系統(tǒng)線程

因此 pthread 是底層機(jī)制,而 OpenMP、oneTBB 和 std::thread 是更高級的編程接口。

新 C++ 項(xiàng)目該用什么

如果是普通現(xiàn)代 C++ 項(xiàng)目,通常優(yōu)先:

#include <thread>

std::thread t([] {
    // 工作
});
t.join();

C++20 中更推薦考慮 std::jthread

#include <thread>

std::jthread t([] {
    // 工作
});

std::jthread 析構(gòu)時(shí)自動(dòng)等待線程,還支持協(xié)作式停止,比直接管理 std::thread 更安全。

只有在以下場景才更可能直接使用 pthread:

  • 項(xiàng)目主體是 C;
  • 必須兼容較老的 C++ 標(biāo)準(zhǔn);
  • 強(qiáng)依賴 POSIX 接口;
  • 需要精細(xì)控制線程調(diào)度、棧和親和性;
  • 正在維護(hù)已有 pthread 項(xiàng)目。

OpenMP 和普通線程的核心差異

假設(shè)要并行處理數(shù)組。

使用 OpenMP:

#pragma omp parallel for
for (int i = 0; i < n; ++i) {
    c[i] = a[i] + b[i];
}

程序員描述的是:

這個(gè)循環(huán)可以并行。

使用線程庫時(shí):

std::vector<std::thread> threads;

for (int t = 0; t < num_threads; ++t) {
    threads.emplace_back([&, t] {
        int begin = t * n / num_threads;
        int end = (t + 1) * n / num_threads;

        for (int i = begin; i < end; ++i) {
            c[i] = a[i] + b[i];
        }
    });
}

for (auto& thread : threads) {
    thread.join();
}

程序員需要自己處理:

  • 創(chuàng)建多少線程;
  • 每個(gè)線程處理哪一段;
  • 如何捕獲變量;
  • 如何等待線程結(jié)束。

因此對于規(guī)則數(shù)值循環(huán),OpenMP 更簡潔;對于復(fù)雜并發(fā)架構(gòu),顯式線程或任務(wù)系統(tǒng)更靈活。

MPI、OpenMP 經(jīng)常一起使用

在超算中,典型模式不是二選一,而是混合并行:

多個(gè)計(jì)算節(jié)點(diǎn)
    ↓ MPI
每個(gè)節(jié)點(diǎn)啟動(dòng)若干 MPI 進(jìn)程
    ↓ OpenMP
每個(gè) MPI 進(jìn)程再啟動(dòng)若干 CPU 線程

例如兩臺節(jié)點(diǎn),每臺 64 核:

每節(jié)點(diǎn) 4 個(gè) MPI 進(jìn)程
每個(gè) MPI 進(jìn)程 16 個(gè) OpenMP 線程
總計(jì):2 × 4 × 16 = 128 個(gè) CPU 核

常見啟動(dòng)方式類似:

export OMP_NUM_THREADS=16
mpirun -np 8 ./program

VASP 就經(jīng)常采用 MPI、OpenMP 和 GPU 加速的組合。

對原表的修正

更合理的評價(jià)是:

技術(shù)定位推薦場景
std::thread / std::jthread標(biāo)準(zhǔn) C++ 線程現(xiàn)代通用 C++
pthreadPOSIX 底層線程C、Linux 系統(tǒng)開發(fā)、底層控制
OpenMP標(biāo)準(zhǔn)化共享內(nèi)存并行 API科學(xué)計(jì)算、規(guī)則循環(huán)
oneTBB任務(wù)并行運(yùn)行時(shí)復(fù)雜任務(wù)圖、線程池
MPI分布式進(jìn)程通信標(biāo)準(zhǔn)集群、超算、多節(jié)點(diǎn)計(jì)算

另外,OpenMP 不是簡單的“編譯器私有擴(kuò)展”,它有獨(dú)立的公開規(guī)范,只是通過編譯器指令和運(yùn)行時(shí)庫實(shí)現(xiàn)。

一句話總結(jié):

普通 C++ 并發(fā)優(yōu)先考慮標(biāo)準(zhǔn)線程或成熟任務(wù)框架;規(guī)則科學(xué)計(jì)算優(yōu)先考慮 OpenMP;跨節(jié)點(diǎn)并行使用 MPI;pthread 更接近 Linux 底層實(shí)現(xiàn)和控制接口。

以上就是C++實(shí)現(xiàn)多線程編程的方式匯總的詳細(xì)內(nèi)容,更多關(guān)于C++多線程編程方式的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C++實(shí)現(xiàn)點(diǎn)云添加高斯噪聲功能

    C++實(shí)現(xiàn)點(diǎn)云添加高斯噪聲功能

    所謂高斯噪聲是指它的概率密度函數(shù)服從高斯分布(即正態(tài)分布)的一類噪聲,這篇文章主要給大家介紹了關(guān)于C++實(shí)現(xiàn)點(diǎn)云添加高斯噪聲功能的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • C語言中聯(lián)合體與共用體和枚舉使用語法示例

    C語言中聯(lián)合體與共用體和枚舉使用語法示例

    這篇文章主要介紹了C語言中聯(lián)合體與共用體和枚舉使用語法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-12-12
  • C語言詳細(xì)講解多維數(shù)組與多維指針

    C語言詳細(xì)講解多維數(shù)組與多維指針

    C 語言中的多維數(shù)組(multidimensional array)其實(shí)就是元素為數(shù)組的數(shù)組。多維指針根據(jù)聲明的維數(shù)需要進(jìn)行多次地址轉(zhuǎn)換才能夠取到目標(biāo)數(shù)據(jù)。但指針作為數(shù)據(jù)變量,可以多次賦值,使其成為對數(shù)組操作訪問的一大利器,所以指針和數(shù)組的結(jié)合才是重中之重
    2022-04-04
  • solaris操作系統(tǒng)做c應(yīng)用程序開發(fā)步驟

    solaris操作系統(tǒng)做c應(yīng)用程序開發(fā)步驟

    solaris操作系統(tǒng)做c應(yīng)用程序開發(fā)步驟,大家參考使用吧
    2013-12-12
  • C語言*與&在操作線性表的作用詳解

    C語言*與&在操作線性表的作用詳解

    本文主要介紹了C語言*與&在操作線性表的作用詳解,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • C++編程歸并排序算法實(shí)現(xiàn)示例

    C++編程歸并排序算法實(shí)現(xiàn)示例

    這篇文章主要為大家介紹了C++編程歸并排序算法實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2021-11-11
  • 詳解Dev C++使用教程(使用Dev C++編寫C語言程序)

    詳解Dev C++使用教程(使用Dev C++編寫C語言程序)

    這篇文章主要介紹了詳解Dev C++使用教程(使用Dev C++編寫C語言程序),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • C++實(shí)現(xiàn)聊天程序

    C++實(shí)現(xiàn)聊天程序

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)類似QQ聊天程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • C語言版約瑟夫問題算法實(shí)現(xiàn)

    C語言版約瑟夫問題算法實(shí)現(xiàn)

    大家好,本篇文章主要講的是C語言版約瑟夫問題算法實(shí)現(xiàn),感興趣的同學(xué)趕快來看一看吧,對你又幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • C++中的移動(dòng)構(gòu)造函數(shù)及move語句示例詳解

    C++中的移動(dòng)構(gòu)造函數(shù)及move語句示例詳解

    這篇文章主要給大家介紹了關(guān)于C++中移動(dòng)構(gòu)造函數(shù)及move語句的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用C++具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-10-10

最新評論

黄浦区| 晋城| 石门县| 南漳县| 喀喇沁旗| 敖汉旗| 葫芦岛市| 安图县| 慈利县| 德格县| 揭西县| 南华县| 青海省| 阳西县| 青龙| 马公市| 西林县| 江源县| 金塔县| 博乐市| 平山县| 临漳县| 扶沟县| 瑞安市| 连城县| 响水县| 肃北| 辽中县| 荆州市| 黄骅市| 桃园市| 崇左市| 扎兰屯市| 鄂伦春自治旗| 饶平县| 五原县| 星子县| 应用必备| 蒲江县| 廊坊市| 武平县|