簡體   English   中英

如何從不同的線程,OpenMP,C ++寫入文件

[英]How to write to file from different threads, OpenMP, C++

我使用openMP並行執行我的C ++程序。 我的並行代碼格式很簡單

#pragma omp parallel for shared(a, b, c) private(i, result)
        for (i = 0; i < N; i++){
         result= F(a,b,c,i)//do some calculation
         cout<<i<<" "<<result<<endl;
         }

如果兩個線程試圖同時寫入文件,則數據會混合在一起。 我該如何解決這個問題?

OpenMP提供了實用程序來幫助進行同步。 #pragma omp critical允許任何時刻(互斥關鍵區域)僅一個線程執行附加的語句。 #pragma omp ordered pragma確保循環迭代線程按順序進入該區域。

// g++ -std=c++11 -Wall -Wextra -pedantic -fopenmp critical.cpp
#include <iostream>

int main()
{
  #pragma omp parallel for
  for (int i = 0; i < 20; ++i)
    std::cout << "unsynchronized(" << i << ") ";
  std::cout << std::endl;
  #pragma omp parallel for
  for (int i = 0; i < 20; ++i)
    #pragma omp critical
    std::cout << "critical(" << i << ") ";
  std::cout << std::endl;
  #pragma omp parallel for ordered
  for (int i = 0; i < 20; ++i)
    #pragma omp ordered
    std::cout << "ordered(" << i << ") ";
  std::cout << std::endl;
  return 0;
}

輸出示例(通常每次都不同):

unsynchronized(unsynchronized(unsynchronized(05) unsynchronized() 6unsynchronized() 1unsynchronized(7) ) unsynchronized(unsynchronized(28) ) unsynchronized(unsynchronized(93) ) unsynchronized(4) 10) unsynchronized(11) unsynchronized(12) unsynchronized(15) unsynchronized(16unsynchronized() 13unsynchronized() 17) unsynchronized(unsynchronized(18) 14unsynchronized() 19) 
critical(5) critical(0) critical(6) critical(15) critical(1) critical(10) critical(7) critical(16) critical(2) critical(8) critical(17) critical(3) critical(9) critical(18) critical(11) critical(4) critical(19) critical(12) critical(13) critical(14) 
ordered(0) ordered(1) ordered(2) ordered(3) ordered(4) ordered(5) ordered(6) ordered(7) ordered(8) ordered(9) ordered(10) ordered(11) ordered(12) ordered(13) ordered(14) ordered(15) ordered(16) ordered(17) ordered(18) ordered(19) 

問題是:您只有一個資源,所有線程都嘗試訪問。 必須保護這些單一資源免受並發訪問(線程安全資源也這樣做,只是對您透明;順便說一句: 是關於std :: cout線程安全的一個不錯的答案)。 您現在可以使用std::mutex保護該單一資源。 然后的問題是,這些線程將不得不等待互斥體,直到另一個線程再次將其返回。 因此,只有在F是一個非常復雜的函數時,您才能從並行化中受益。

進一步的缺點:由於線程並行工作,即使使用互斥量來保護std :: in,結果也可以按任意順序打印出來,具體取決於哪個線程較早運行。

如果我假設您希望在較小的i之前讓F(... i)的結果在較大i的結果之前,則應該完全放棄並行化,或者以不同的方式進行:

提供一個大小為N的數組,並讓每個線程將其結果存儲在那里( array[i] = f(i); )。 然后在單獨的非並行循環中遍歷數組。 同樣,只有在F是一個復數函數(對於N大)時,這樣做才值得付出努力。

另外:請注意,也必須創建線程,這會在某些地方造成一些開銷(創建線程基礎結構和堆棧,在OS上注冊線程,... –除非您可以重用早先在線程池中創建的某些線程... )。 在決定是否要並行化時也要考慮這一點。 有時,非並行計算會更快...

暫無
暫無

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

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