2016-10-13 109 views
4

我是C++的新手,我來自Python的長篇背景。C++中的類似Python的多處理

我正在尋找一種在C++中並行運行函數的方法。我讀了很多關於std::async的內容,但對我而言仍然不是很清楚。

  1. 下面的代碼做一些真正有趣的事情

    #include <future> 
    #include <iostream> 
    
    void called_from_async() { 
        std::cout << "Async call" << std::endl; 
    } 
    
    int main() { 
        //called_from_async launched in a separate thread if possible 
        std::future<void> result(std::async(called_from_async)); 
    
        std::cout << "Message from main." << std::endl; 
    
        //ensure that called_from_async is launched synchronously 
        //if it wasn't already launched 
        result.get(); 
    
        return 0; 
    } 
    

    如果我跑了好幾次,有時輸出是我所期待的:

    Message from main. 
    Async call 
    

    但有時我得到這樣的事情:

    MAessysnacg ec aflrlom main. 
    

    爲什麼不是cout首先發生?我清楚地在cout之後調用.get()方法。

  2. 關於平行運行。如果我有這樣的代碼:

    #include <future> 
    #include <iostream> 
    #include <vector> 
    
    int twice(int m) { 
        return 2 * m; 
    } 
    
    int main() { 
        std::vector<std::future<int>> futures; 
    
        for(int i = 0; i < 10; ++i) { 
        futures.push_back (std::async(twice, i)); 
        } 
    
        //retrive and print the value stored in the future 
        for(auto &e : futures) { 
        std::cout << e.get() << std::endl; 
        } 
    
        return 0; 
    } 
    

    所有10個調用twice函數將在不同的內核上同時運行?

    如果不是,那麼在C++中是否有類似的東西,如Python 多進程 lib?

    主要是什麼我正在尋找:

    我寫一個函數,並與具有多輸入n個稱呼它?並且它將在n個節點上同時運行該功能1次。

+3

因爲'std :: cout'是內部同步的,所以你的結果應該不會**發生。這實際上是你看到的確切結果嗎?如果是這樣,那是一個編譯器錯誤。 - 另一個評論,請不要將行號添加到您要發佈的代碼中,這會讓其他人難以複製並粘貼它來嘗試代碼。 –

+0

至於** 1 **:你想要平行運行,然後當他們平行運行時你感到驚訝嗎? – Biffen

+0

@Biffen在並行處理中,我並不感到驚訝,但是當你看到第一個'cout'並不平行時,並行處理只被稱爲ONCE和'cout'後。這是什麼讓人困惑 –

回答

5

1)result.get();不啓動線程。它只有等待的結果。並行線程通過調用std::async(called_from_async)(或編譯器決定)啓動。

std::cout保證是內部線程安全的。因此,您向我們展示的結果應該不會發生。有一個競爭條件,但你不能混合這樣的輸出。如果真的發生(我懷疑),那麼你可能正在處理一個編譯器錯誤。

2)您的電話將並行運行。有多少核心依賴於您的計算機上運行的操作系統和其他進程。但是很有可能所有的都會被使用(假設你可以控制整個生態系統,並且沒有其他的CPU密集型進程在後臺運行)。

C++沒有類似多處理的lib(至少不在std中)。如果你想運行子進程,那麼有幾個選項,例如分叉或者popen系統調用。

+0

完美,謝謝。還有一個問題:我可以以某種方式指定我希望使用的核心數量,否則C++將使用所有可用的核心數量? –

+1

@GáborErdős完全取決於您使用的操作系統。有些人可能會讓你有能力手動挑選核心。 AFAIK在posix和windows上都是可能的,但我不會走這條路 - 它很混亂,需要很多關於內核的知識。另請注意,多處理可解決相同的問題。 – freakish

+0

我只問,因爲我打算在HPC上使用腳本。如果它使用所有可用的內核對我來說都是okey,那只是好奇。在python多處理中,我可以定義一個'Pool(4)',它將運行在4個內核上。 –