深入理解thread join

一、thread join簡介

thread join是線程同步的一種機制,它能夠在一個線程中等待另一個線程執行完畢之後再繼續執行。

線程是計算機操作系統中最小的執行單位,如果一個進程需要同時處理多個任務,那麼可以創建多個線程來同時處理任務,這減少了進程切換和創建線程的開銷,提高了執行效率。

在這種多線程的情況下,為了保證任務完成的正確性,我們要考慮線程之間的同步問題,這就是thread join可以解決的問題。

二、使用thread join實現線程同步

一般情況下,主線程會創建多個子線程,這些子線程會在執行自己的任務的同時,還需要等待其他子線程執行完畢之後才能繼續執行。這個時候就需要使用thread join來實現。

下面示例代碼創建了三個線程,它們每個都會打印1到5,但是要求線程1必須先打印1到5,然後線程2打印1到5,最後線程3打印1到5。

#include <thread>
#include <iostream>
#include <mutex>

// 每個線程都要輸出1到5,但必須保證線程1先輸出,線程2其次,線程3最後
std::mutex mtx;
void printNum(int num, int threadNum) {
    for (int i = 1; i <= 5; i++) {
        // 保證每個線程輸出時不會被阻塞
        std::unique_lock<std::mutex> lck(mtx);
        if (threadNum == 1) {
            std::cout << "Thread1:" << num++ << std::endl;
        } else if (threadNum == 2) {
            std::cout << "Thread2:" << num++ << std::endl;
        } else if (threadNum == 3) {
            std::cout << "Thread3:" << num++ << std::endl;
        }
    }
}

int main() {
    int num = 1;

    // 創建三個線程,並讓它們輸出
    std::thread t1(printNum, num, 1);
    std::thread t2(printNum, num, 2);
    std::thread t3(printNum, num, 3);

    // 等待三個線程都執行完畢
    t1.join();
    t2.join();
    t3.join();
   
    return 0;
}

在這個示例代碼中,我們使用了mutex來保證多線程的安全性,同時使用了unique_lock來保證每個線程輸出時不會被阻塞。最後在主線程中使用了join函數,來保證每個子線程都執行完畢之後,主線程再繼續執行。

三、thread join的使用注意事項

1、注意線程的生命周期

在使用thread join的時候,一定要注意線程的生命周期,如果一個線程被join之後,就不能再次使用該線程對象進行join,否則會拋出系統異常。

#include <thread>
#include <iostream>

void hello() {
    std::cout << "Hello World!" << std::endl;
}

int main() {
    std::thread t(hello);

    // 等待線程t執行完畢
    t.join();

    // 再次等待線程t執行完畢,會拋出異常
    t.join();
   
    return 0;
}

2、join的執行順序

如果有多個線程需要執行join操作,那麼它們的執行順序也是需要注意的。一般情況下,應該按照子線程的創建順序依次執行join,這樣才能保證主線程能夠等待所有子線程都執行完畢之後再繼續執行。

#include <thread>
#include <iostream>

void printNum(int num) {
    std::cout << num << std::endl;
}

int main() {
    std::thread t1(printNum, 1);
    std::thread t2(printNum, 2);
    std::thread t3(printNum, 3);

    // 等待t2線程執行完畢
    t2.join();
    // 等待t3線程執行完畢
    t3.join();
    // 等待t1線程執行完畢
    t1.join();
   
    return 0;
}

3、對於同一個線程只能調用一次join

如果對於同一個線程多次調用join函數,那麼只有第一次會生效,其他的調用會被忽略。

#include <thread>
#include <iostream>

void hello(int num) {
    std::cout << "Hello World " << num << std::endl;
}

int main() {
    std::thread t(hello, 1);

    // 等待t線程執行完畢
    t.join();

    // 再次等待t線程執行完畢,會被忽略
    t.join();
   
    return 0;
}

四、總結

Thread join是線程同步的一種機制,它能夠在一個線程中等待另一個線程執行完畢之後再繼續執行。在使用thread join的時候,一定要注意線程的生命周期,以及join的執行順序和對於同一個線程只能調用一次join。

使用thread join能夠解決多線程競爭的問題,提高程序的可靠性和可維護性。在實際的開發過程中,我們需要根據具體的場景來決定是否需要使用thread join,以及如何使用thread join。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/198593.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-04 10:25
下一篇 2024-12-04 10:26

相關推薦

  • Java Thread.start() 執行幾次的相關問題

    Java多線程編程作為Java開發中的重要內容,自然會有很多相關問題。在本篇文章中,我們將以Java Thread.start() 執行幾次為中心,為您介紹這方面的問題及其解決方案…

    編程 2025-04-29
  • Python中字符串join方法解析

    join是一個非常實用的字符串方法,它可以用於將序列中的元素連接成一個字符串。以下是關於Python中字符串join方法的詳細解析。 一、基本使用 join方法是在一個字符串列表或…

    編程 2025-04-27
  • 深入解析Vue3 defineExpose

    Vue 3在開發過程中引入了新的API `defineExpose`。在以前的版本中,我們經常使用 `$attrs` 和` $listeners` 實現父組件與子組件之間的通信,但…

    編程 2025-04-25
  • 深入理解byte轉int

    一、字節與比特 在討論byte轉int之前,我們需要了解字節和比特的概念。字節是計算機存儲單位的一種,通常表示8個比特(bit),即1字節=8比特。比特是計算機中最小的數據單位,是…

    編程 2025-04-25
  • 深入理解Flutter StreamBuilder

    一、什麼是Flutter StreamBuilder? Flutter StreamBuilder是Flutter框架中的一個內置小部件,它可以監測數據流(Stream)中數據的變…

    編程 2025-04-25
  • 深入探討OpenCV版本

    OpenCV是一個用於計算機視覺應用程序的開源庫。它是由英特爾公司創建的,現已由Willow Garage管理。OpenCV旨在提供一個易於使用的計算機視覺和機器學習基礎架構,以實…

    編程 2025-04-25
  • 深入了解scala-maven-plugin

    一、簡介 Scala-maven-plugin 是一個創造和管理 Scala 項目的maven插件,它可以自動生成基本項目結構、依賴配置、Scala文件等。使用它可以使我們專註於代…

    編程 2025-04-25
  • 深入了解LaTeX的腳註(latexfootnote)

    一、基本介紹 LaTeX作為一種排版軟件,具有各種各樣的功能,其中腳註(footnote)是一個十分重要的功能之一。在LaTeX中,腳註是用命令latexfootnote來實現的。…

    編程 2025-04-25
  • 深入探討馮諾依曼原理

    一、原理概述 馮諾依曼原理,又稱“存儲程序控制原理”,是指計算機的程序和數據都存儲在同一個存儲器中,並且通過一個統一的總線來傳輸數據。這個原理的提出,是計算機科學發展中的重大進展,…

    編程 2025-04-25
  • 深入理解Python字符串r

    一、r字符串的基本概念 r字符串(raw字符串)是指在Python中,以字母r為前綴的字符串。r字符串中的反斜杠(\)不會被轉義,而是被當作普通字符處理,這使得r字符串可以非常方便…

    編程 2025-04-25

發表回復

登錄後才能評論