C++多線程編程:std::thread的用法

一、std::thread概述

std::thread是C++11提供的多線程庫之一,它提供了一種方便的方式來並行執行代碼,將多個任務同時執行。

std::thread庫提供了創建線程、等待線程結束和管理線程的方法。在std::thread庫中,我們可以使用std::thread對象的構造函數來創建一個新的線程,並告訴它應該執行哪個函數或lambda表達式。當執行完畢時,線程對象可以用join()或detach()方法來終止線程並等待它的結束。

void func1()
{
    // ...
}

int main()
{
    std::thread t(func1);
    // ...
    t.join();
    return 0;
}

在上面的代碼中,我們定義了一個名為func1()的函數,並使用std::thread對象t在新線程中執行func1()函數。使用join()方法等待線程結束。在主線程中,我們可以執行其他操作,並在最後等待線程結束。

二、std::thread的創建和聲明

std::thread對象的創建方式有多種方法,這裡列舉其中的兩種方法。

第一種,使用函數指針創建線程:

// 一個簡單的函數
void task1(int n)
{
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    std::cout << "task1: " << n << std::endl;
}

int main()
{
   std::thread t(task1, 1); // task1函數的參數是1
   std::cout << "main thread\n";
   t.join();
   return 0;
}

第二種,使用lambda表達式創建線程:

int main()
{
    std::thread t([](int n) {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        std::cout << "task2: " << n << std::endl;
    }, 2);
    std::cout << "main thread\n";
    t.join();
    return 0;
}

注意:使用lambda表達式時,需要在參數列表中指定要傳遞給線程的值。

三、std::thread的數據共享和同步

多線程編程時,可能會遇到數據共享和同步的問題。對於數據共享的問題,很容易就會想到使用全局數據或靜態數據。

// 全局變量
int g_count = 0;

void task1()
{
    for (int i = 0; i < 5; ++i) {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        ++g_count;
    }
}

int main()
{
    std::thread t1(task1);
    std::thread t2(task1);

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

    std::cout << "g_count = " << g_count << std::endl;
    return 0;
}

然而,在多個線程中同時訪問全局變量或靜態變量時,可能會出現數據競爭。在上面的示例中,我們想要將g_count變量遞增五次,但在實際執行過程中,可能出現每個線程各自的計數和。

因此,我們需要使用互斥量來同步訪問。

std::mutex g_mutex;
int g_count = 0;

void task2()
{
    for (int i = 0; i < 5; ++i) {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        std::lock_guard<std::mutex> lock(g_mutex);
        ++g_count;
    }
}

int main()
{
    std::thread t3(task2);
    std::thread t4(task2);

    t3.join();
    t4.join();

    std::cout << "g_count = " << g_count << std::endl;
    return 0;
}

在上面的示例中,我們使用了互斥量g_mutex,通過std::lock_guard<std::mutex> lock(g_mutex)來保護對g_count變量的訪問。

四、std::thread的一些其他方法

std::thread還提供了一些其他方法來管理線程。

在主線程中,我們可以通過調用std::this_thread::get_id()來獲取當前線程的id。

std::cout << "main thread id = " << std::this_thread::get_id() << std::endl;

在線程中,我們可以使用std::thread::yield()來暫停當前線程,允許其他線程執行。

void task3()
{
    for (int i = 0; i < 5; ++i) {
        std::this_thread::yield();
        std::cout << "task3\n";
    }
}

int main()
{
    std::thread t5(task3);

    for (int i = 0; i < 5; ++i) {
        std::cout << "main\n";
    }

    t5.join();
    return 0;
}

在上面的示例中,我們通過std::thread::yield()方法來將控制權交給其他線程,以便其他線程有機會執行。

std::thread還提供了detach()方法來在後台運行線程。

void task4()
{
    for (int i = 0; i < 5; ++i) {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        std::cout << "task4: " << i << std::endl;
    }
}

int main()
{
    std::thread t6(task4);
    t6.detach();
    std::cout << "main thread\n";
    return 0;
}

在上面的示例中,我們使用detach()方法來後台運行線程t6,並且在主線程中繼續執行其他操作。

五、std::thread的注意事項

在使用std::thread時,需要注意以下幾點:

  • 使用std::this_thread::sleep_for()或std::this_thread::sleep_until()代替std::sleep()。
  • 不能將std::thread對象的拷貝賦值給其他變量或傳遞給函數。
  • std::thread應該在函數結束前被join()或detach()。
  • 對於臨界區的訪問,應該使用std::lock_guard<std::mutex>或std::unique_lock<std::mutex>。

六、總結

本文介紹了std::thread庫的一些基本用法,包括聲明和創建線程、線程的數據共享和同步、std::thread的一些其他方法以及注意事項。在多線程編程時,需要特別注意線程安全和數據同步,避免出現數據競爭等問題。

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

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
RVUP的頭像RVUP
上一篇 2024-10-03 23:59
下一篇 2024-10-03 23:59

相關推薦

  • Python多線程讀取數據

    本文將詳細介紹多線程讀取數據在Python中的實現方法以及相關知識點。 一、線程和多線程 線程是操作系統調度的最小單位。單線程程序只有一個線程,按照程序從上到下的順序逐行執行。而多…

    編程 2025-04-29
  • Java Thread.start() 執行幾次的相關問題

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

    編程 2025-04-29
  • 多線程和多進程的應用

    多線程和多進程是現代編程中常用的技術,可以提高程序的效率和性能。本文將從不同的角度對多線程和多進程進行詳細的介紹和應用。 一、多線程 vs 多進程 多線程和多進程都是為了實現程序並…

    編程 2025-04-27
  • Python多線程模塊實踐

    本文將向大家介紹Python中的多線程模塊,並通過示例代碼來展示如何靈活使用線程提升程序的性能。同時,本文還將討論Python多線程模塊使用中可能遇到的一些問題及其解決方法。 一、…

    編程 2025-04-27
  • 用c++實現信號量操作,讓你的多線程程序輕鬆實現同步

    在多線程編程中,線程之間的同步問題是非常重要的。信號量是一種解決線程同步問題的有效機制。本文將介紹如何使用C++實現信號量操作,讓你的多線程程序輕鬆實現同步。在介紹實現方法之前,我…

    編程 2025-04-25
  • 多線程編程中的pthread_create函數詳解

    一、概述 在多線程編程中,pthread_create是一個十分重要的函數,它用於創建一個新的線程,並在新線程中執行一個用戶指定的函數。本篇文章將從以下幾個方面對pthread_c…

    編程 2025-04-24
  • NSOperation:iOS多線程編程的不二選擇

    一、什麼是NSOperation? NSOperation是在iOS開發中用於管理多線程編程的類,它是一套基於GCD(Grand Central Dispatch)的高層抽象。NS…

    編程 2025-04-12
  • matlab std詳解

    一、簡介 Matlab是一種強大的計算機程序,可以用來進行數值分析和計算,它可以幫助您完成許多其他編程語言所無法實現的任務。Matlab STD則是一種常用的Matlab工具箱,它…

    編程 2025-03-12
  • 深入了解 Swift 多線程

    一、基本概念 Swift 作為一門面向對象編程語言,自然也支持多線程編程。在 Swift 中,我們可以使用 GCD (Grand Central Dispatch)、NSOpera…

    編程 2025-02-25
  • 多線程事務控制

    一、基本概念 事務是指作為單一邏輯工作單元執行的一系列操作。多線程事務控制就是在多線程並發環境下對事務進行管理和控制,保證事務的原子性、一致性、隔離性和持久性。 原子性是指事務中的…

    編程 2025-02-24

發表回復

登錄後才能評論