2012-05-12 22 views
4

私は、OpenMPを使用していますが、次のようにのように私のプログラムに見えます:fprintfコマンドの1行はスレッドセーフですか?

\#pragma omp parallel for 

for(x = 0, y = 0, x < 5, x++, y++) 

    function(x, y, fp); 

void function(int x , int y, FILE* fp); 
{ 
    fprintf(fp, "(%d, %d)\n", x y); 
} 

は私が

(0, 0) 
(2, 2) 
(1, 1) 
(3, 3) 
(4, 4) 
順序は重要ではありません

としてファイルの内容が、座標x、yがなければならないことを望みますすなわち、プログラムは(2,3)のようなものを生成すべきではありません。この動作は常に保証されていますか?私はLinux上でgccコンパイラを使用しています。

+0

私は確信しているとは思っていますが、確かめたいのであれば、(write)システムコールを直接呼び出すことができます。 –

+0

@KerrekSB、ありがとう、私はこのプログラムを複数回(ループカウンタを増やして)実行しましたが、毎回正しい出力を生成するようです。 – quartz

+2

可能な複製http://stackoverflow.com/questions/467938/stdout-thread-safe-in-c-on-linux – Tudor

答えて

3

あなたの質問には互換性のない仮定があります。 OpenMpはC標準の一部ではないので、C仕様ではOpenMpのスレッドモデルについて何も言えず、適切な関数の安全性について何も保証していません。最近までCはスレッドモデルを持っていませんでした。

C11は現在、自身のスレッドモデルを有しており、そのスレッドモデルでIOストリームを操作する関数は、スレッドセーフである:

各ストリームは 場合、複数のデータ競合を防止するために使用される関連するロックを有しています実行スレッドはストリームにアクセスし、複数のスレッドによって実行されるストリーム操作のインターリーブを制限することができます。 一度に1つのスレッドのみがこのロックを保持できます。ロックは再入可能です。 単一スレッドは、指定された時間にロックを複数回保持できます。

私はC11を完全に実装するコンパイラはまだありませんが、通常POSIXシステムのCライブラリはこの特定の要件を満たすでしょう。そのような準拠した実装があるとき、そのスレッドモデルがC11のものと一致するかどうかを文書化するために、OpenMpの実装に依存します。

+0

"典型的な"だけではありません。 POSIXでは、stdio 'FILE'上のすべての操作がスレッドに関して原子的に振舞うことが要求されます。複数の別々のstdio呼び出しをアトミック操作にグループ化する場合は、 'flockfile'関数と' funlockfile'関数(POSIX)を使用できます。 –

+0

@ R。確かに。私は、この要件が満たされているシステムファミリの1つの例の「典型的な」を意味しました。私は他のシステムが同様のことをしているのかどうか、POSIXの中世の実装(例えばOS Xなど)がこれを持っているのかどうかはわかりません。 IRIX(POSIXとされていたと思われる)をプログラミングするとき、異なるスレッドからの絡み合ったIOに関する多くの問題があったことを覚えています。 –

関連する問題