[英]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.