Как я могу использовать PIPE буфер ввода или вывода файла flu sh? - PullRequest
0 голосов
/ 16 июня 2020

сегодня у моего кода проблема с буфером ввода и вывода flu sh проблема.

эта проблема

код первого процесса (# 1) ....

int sign_sender(char* command)
{
    int f , len;

    f=open(PIPE_NAME,O_RDWR);

    if(f<0)
    {
        printf("open fail : %s\n",strerror(errno));
        exit(1);
    }

    while(1)
    {
        len=strlen(command);
        if(len<=0)
        {
            continue;
        }
        write(f,command,len);
        printf("write...\n");
        sleep(1);
    }
    return 1;
}

это строка записи без блокировки ...

и.

Второй процесс (# 2) - это ...

int sign_receiver()
{
    int f , len;
    char temp_buffer[128]={0};

    f=open(PIPE_NAME,O_RDWR|O_NONBLOCK);
    if(f<0)
    {
        printf("open fail \n");
        exit(1);
    }

    while(1)
    {
        if((len=read(f,temp_buffer,sizeof(temp_buffer)))<0)
        {
            printf("read error. len = %d\n",len);
        }
        printf("read...\n");
        if(len>0)
        {
            printf("len : %d , sign process recv : [%s]\n",len,temp_buffer);
        }
        sleep(1);
    }

    close(f);
    unlink(PIPE_NAME);

    return 1;
} 

вот так. процесс (# 1) запускается первым. и 5 se c после запуска процесса (# 2) ..

printf процесса (# 2) ....

read...
len : 15 , sign process recv : [hellohellohello]
read...
len : 5 , sign process recv : [hellohellohello]
read...
len : 5 , sign process recv : [hellohellohello]
read...
len : 5 , sign process recv : [hellohellohello]
read...
len : 5 , sign process recv : [hellohellohello]
read...
len : 5 , sign process recv : [hellohellohello]

Мне нужен этот printf.

read...
len : 5 , sign process recv : [hello]
read...
len : 5 , sign process recv : [hello]
read...
len : 5 , sign process recv : [hello]
read...
len : 5 , sign process recv : [hello]

не знаю почему .... я такой нуб из C ...

1 Ответ

0 голосов
/ 16 июня 2020

Причина, по которой [hellohellohello] продолжает записываться после первого чтения, заключается в том, что вы не очищаете буфер между каждой операцией чтения. Итак, что вы на самом деле видите в следующих строках, где написано:

len: 5, подпишите процесс recv: [hellohellohello]

Это сообщение hello , которое было только что прочитано, и которое переопределило 5 первых букв, содержащихся в предыдущем состоянии вашего буфера, за которыми следовало то, что осталось в буфере, следовательно, повторение сообщения.

Вот пример того, как вы может очистить буфер:

int sign_receiver()
{
    int f , len;
    char temp_buffer[128]={0};

    f=open(PIPE_NAME,O_RDWR|O_NONBLOCK);
    if(f<0)
    {
        printf("open fail \n");
        exit(1);
    }

    while(1)
    {
        if((len=read(f,temp_buffer,sizeof(temp_buffer)))<0)
        {
            printf("read error. len = %d\n",len);
        }
        printf("read...\n");
        if(len>0)
        {
            printf("len : %d , sign process recv : [%s]\n",len,temp_buffer);
            memset(temp_buffer, 0, 128); <- Adding this line
        }
        sleep(1);
    }

    close(f);
    unlink(PIPE_NAME);

    return 1;
}

Но это не избавит вас от первого [hellohellohello] , потому что вы несколько раз пишете в именованный канал перед чтением это (3 раза в вашем случае). Эти сообщения буферизуются в системном буфере до тех пор, пока они не будут извлечены вызовами чтения.

Ваше неблокирующее чтение не означает, что оно отбрасывает накопленные данные, накопленные в системном буфере, это просто означает что его вызов вернется немедленно, даже если данные не были прочитаны.

Я бы предложил инвертировать порядок, в котором вы вызываете два процесса, выполняя исполняемый файл 2 перед исполняемым файлом 1, если вам не нужны сообщения для суммирования при первом чтении.

Вы также можете добавить дополнительное определение в свои сообщения с верхним / нижним колонтитулом или разделителем, который позволит вам анализировать сообщения внутри полезной нагрузки.

...