Linux - именованные каналы - потеря данных - PullRequest
1 голос
/ 01 февраля 2011

Я использую именованные каналы для IPC. Иногда данные, передаваемые между процессами, могут быть большими и частыми. За это время я вижу много потери данных. Есть ли какие-либо очевидные проблемы в приведенном ниже коде, которые могут вызвать это?

Спасибо

#!/usr/bin/env groovy
import java.io.FileOutputStream;
def bytes = new File('/etc/passwd').bytes
def pipe = new File('/home/mohadib/pipe')
1000.times{
    def fos = new FileOutputStream(pipe)
    fos.write(bytes)
    fos.flush()
    fos.close()
}


#!/usr/bin/env groovy
import java.io.FileInputStream;
import java.io.ByteArrayOutputStream;

def pipe = new File('/home/mohadib/pipe')
def bos = new ByteArrayOutputStream()
def len = -1
byte[] buff = new byte[8192]
def i = 0
while(true)
{
    def fis = new FileInputStream(pipe)
    while((len = fis.read(buff)) != -1) bos.write(buff, 0, len)
    fis.close()
    bos.reset()
    i++
    println i
}

Ответы [ 2 ]

2 голосов
/ 02 февраля 2011

Именованные каналы теряют свое содержимое, когда последний процесс закрывает их. В вашем примере это может произойти, если процесс записи выполняет другую итерацию, в то время как процесс чтения собирается выполнить fis.close(). В этом случае не сообщается об ошибке.

Возможное исправление состоит в том, чтобы процесс чтения никогда не закрывал fifo. Чтобы избавиться от условия EOF при отключении последнего записывающего устройства, откройте fifo для записи, закройте конец чтения, снова откройте конец чтения и закройте конец временной записи.

2 голосов
/ 02 февраля 2011

Этот раздел доставляет мне беспокойство:

1000.times{
    def fos = new FileOutputStream(pipe)
    fos.write(bytes)
    fos.flush()
    fos.close()
}

Я знаю, что базовый системный вызов Unix write () не всегда записывает запрошенное количество байтов .Вы должны проверить возвращаемое значение, чтобы увидеть, какое число действительно было написано.

Я проверил документы для Java, и оказалось, что fos.write () не имеет возвращаемого значения, он просто выдает IOException, если что-то пойдет не так.Что Groovy делает с исключениями?Есть ли какие-то исключения?

Если вы можете, запустите это в режиме strace и просмотрите результаты системных вызовов read и write.Вполне возможно, что Java VM не работает правильно с системным вызовом write ().Я знаю, что это может произойти, потому что я поймал реализацию fwrite в glibc, которая делала это (игнорируя возвращаемое значение) два года назад.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...