簡體   English   中英

C++ 中線程的簡單示例

[英]Simple example of threading in C++

有人可以發布一個在 C++ 中啟動兩個(面向對象)線程的簡單示例。

我正在尋找可以擴展運行方法(或類似的東西)而不是調用 C 樣式線程庫的實際 C++ 線程對象。

我省略了任何特定於操作系統的請求,希望回復的人會回復要使用的跨平台庫。 我現在只是明確說明這一點。

創建一個您希望線程執行的函數,例如:

void task1(std::string msg)
{
    std::cout << "task1 says: " << msg;
}

現在創建最終將調用上述函數的thread對象,如下所示:

std::thread t1(task1, "Hello");

(您需要#include <thread>才能訪問std::thread類)

構造函數的參數是線程將執行的函數,后跟函數的參數。 線程在構造時自動啟動。

如果稍后您想等待線程完成執行函數,請調用:

t1.join(); 

(加入意味着調用新線程的線程將等待新線程完成執行,然后才能繼續自己的執行)。


編碼

#include <string>
#include <iostream>
#include <thread>

using namespace std;

// The function we want to execute on the new thread.
void task1(string msg)
{
    cout << "task1 says: " << msg;
}

int main()
{
    // Constructs the new thread and runs it. Does not block execution.
    thread t1(task1, "Hello");

    // Do other things...

    // Makes the main thread wait for the new thread to finish execution, therefore blocks its own execution.
    t1.join();
}

關於 std::thread 的更多信息在這里

  • 在 GCC 上,使用-std=c++0x -pthread編譯。
  • 這應該適用於任何操作系統,前提是您的編譯器支持此 (C++11) 功能。

好吧,從技術上講,任何這樣的對象最終都會在 C 風格的線程庫上構建,因為 C++ 只是在 c++0x 中指定了一個股票std::thread模型,它剛剛確定並且尚未實現。 這個問題有點系統性,從技術上講,現有的 c++ 內存模型不夠嚴格,無法為所有“發生在之前”的情況提供明確定義的語義。 Hans Boehm 不久前寫了一篇關於該主題的論文,並在制定有關該主題的 c++0x 標准方面發揮了重要作用。

http://www.hpl.hp.com/techreports/2004/HPL-2004-209.html

也就是說,有幾個跨平台線程 C++ 庫在實踐中工作得很好。 Intel 線程構建塊包含一個 tbb::thread 對象,該對象非常接近 c++0x 標准,而 Boost 有一個 boost::thread 庫,可以執行相同的操作。

http://www.threadingbuildingblocks.org/

http://www.boost.org/doc/libs/1_37_0/doc/html/thread.html

使用 boost::thread 你會得到類似的東西:

#include <boost/thread.hpp>

void task1() { 
    // do stuff
}

void task2() { 
    // do stuff
}

int main (int argc, char ** argv) {
    using namespace boost; 
    thread thread_1 = thread(task1);
    thread thread_2 = thread(task2);

    // do other stuff
    thread_2.join();
    thread_1.join();
    return 0;
}

還有一個用於 POSIX 操作系統的 POSIX 庫。 檢查兼容性

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <iostream>

void *task(void *argument){
      char* msg;
      msg = (char*)argument;
      std::cout<<msg<<std::endl;
}

int main(){
    pthread_t thread1, thread2;
    int i1,i2;
    i1 = pthread_create( &thread1, NULL, task, (void*) "thread 1");
    i2 = pthread_create( &thread2, NULL, task, (void*) "thread 2");

    pthread_join(thread1,NULL);
    pthread_join(thread2,NULL);
    return 0;

}

用 -lpthread 編譯

http://en.wikipedia.org/wiki/POSIX_Threads

#include <thread>
#include <iostream>
#include <vector>
using namespace std;

void doSomething(int id) {
    cout << id << "\n";
}

/**
 * Spawns n threads
 */
void spawnThreads(int n)
{
    std::vector<thread> threads(n);
    // spawn n threads:
    for (int i = 0; i < n; i++) {
        threads[i] = thread(doSomething, i + 1);
    }

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

int main()
{
    spawnThreads(10);
}

在搜索在新線程中調用其自己的實例方法之一的 C++ 類的示例時,會出現這個問題,但我們無法以這種方式使用這些答案中的任何一個。 這是一個這樣做的例子:

類.h

class DataManager
{
public:
    bool hasData;
    void getData();
    bool dataAvailable();
};

類.cpp

#include "DataManager.h"

void DataManager::getData()
{
    // perform background data munging
    hasData = true;
    // be sure to notify on the main thread
}

bool DataManager::dataAvailable()
{
    if (hasData)
    {
        return true;
    }
    else
    {
        std::thread t(&DataManager::getData, this);
        t.detach(); // as opposed to .join, which runs on the current thread
    }
}

請注意,此示例未涉及互斥鎖或鎖定。

除非想要在全局命名空間中使用單獨的函數,否則我們可以使用 lambda 函數來創建線程。

使用 lambda 創建線程的主要優點之一是我們不需要將本地參數作為參數列表傳遞。 我們可以使用捕獲列表,並且 lambda 的閉包屬性將處理生命周期。

這是一個示例代碼

int main() {
    int localVariable = 100;

    thread th { [=](){
        cout<<"The Value of local variable => "<<localVariable<<endl;
    }};

    th.join();

    return 0;
}

到目前為止,我發現 C++ lambdas 是創建線程的最佳方式,尤其是對於更簡單的線程函數

這在很大程度上取決於您決定使用的庫。 例如,如果您使用 wxWidgets 庫,線程的創建將如下所示:

class RThread : public wxThread {

public:
    RThread()
        : wxThread(wxTHREAD_JOINABLE){
    }
private:
    RThread(const RThread &copy);

public:
    void *Entry(void){
        //Do...

        return 0;
    }

};

wxThread *CreateThread() {
    //Create thread
    wxThread *_hThread = new RThread();

    //Start thread
    _hThread->Create();
    _hThread->Run();

    return _hThread;
}

如果您的主線程調用 CreateThread 方法,您將創建一個新線程,該線程將開始執行“Entry”方法中的代碼。 在大多數情況下,您必須保留對線程的引用才能加入或停止它。 更多信息: wxThread 文檔

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM