名前付きパイプへの読み取り/書き込みを行う2つのスレッドを持つ同じプロセスの範囲内で、リーダー/ライターをまったくブロックしないと思いますか? タイミングが悪いと、一部のデータを見逃す可能性がありますか?
また、複数のプロセスの場合、リーダーはデータが利用可能になるまで待機し、リーダーが提供するすべてのデータをリーダーが読み取るまでライターはブロックされますか?
名前付きパイプを使用して、外部プロセスからいくつか (数十、数百) のファイルを渡し、Java アプリケーションでファイルを使用することを計画しています。1 つのスレッドをパイプへの書き込み用に使用し、別のスレッドをパイプからの読み取り用に使用する単純な単体テストを作成すると、データ チャンクの欠落が原因で散発的なテスト エラーが発生しました。
スレッド化と同じプロセスが原因だと思うので、私のテストは一般的に正しくありません。この仮定は正しいですか?
以下は、このケースを説明するある種の例です。
import java.io.{FileOutputStream, FileInputStream, File}
import java.util.concurrent.Executors
import org.apache.commons.io.IOUtils
import org.junit.runner.RunWith
import org.scalatest.FlatSpec
import org.scalatest.junit.JUnitRunner
@RunWith(classOf[JUnitRunner])
class PipeTest extends FlatSpec {
def md5sum(data: Array[Byte]) = {
import java.security.MessageDigest
MessageDigest.getInstance("MD5").digest(data).map("%02x".format(_)).mkString
}
"Pipe" should "block here" in {
val pipe = new File("/tmp/mypipe")
val srcData = new File("/tmp/random.10m")
val md5 = "8e0a24d1d47264919f9d47f5223c913e"
val executor = Executors.newSingleThreadExecutor()
executor.execute(new Runnable {
def run() {
(1 to 10).foreach {
id =>
val fis = new FileInputStream(pipe)
assert(md5 === md5sum(IOUtils.toByteArray(fis)))
fis.close()
}
}
})
(1 to 10).foreach {
id =>
val is = new FileInputStream(srcData)
val os = new FileOutputStream(pipe)
IOUtils.copyLarge(is, os)
os.flush()
os.close()
is.close()
Thread.sleep(200)
}
}
}
Thread.sleep(200)がないと、テストに合格できません。
- 壊れたパイプの例外
- 不正な MD5 合計
この遅延セットを使用すると、うまく機能します。10 メガバイトのランダム データを含むファイルを使用しています。