簡體   English   中英

C pipe 寫入/讀取雙打序列失敗

[英]C pipe to write / read sequence of doubles fails

對於這個 C 項目,我正在嘗試使用 pipe 來讓父進程與子進程進行通信。 孩子應該從 txt 文件(包含實數)中讀取行(每秒一行)並使用 pipe 來提供父級,而后者又應該從 pipe 讀取並將數字寫入日志文件。 然而父進程只讀取 0.000000 的序列。 這是我的代碼:

#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <wait.h>
#define MAX_I 5
#define delay 1
void read_input(FILE *fp);

FILE *file_log;
int status;
pid_t pid;
int pipeFD[2];

int main(int argc, char **argv) {
//initialize
    FILE *fp;

    if (argc != 2){
    if ((fp = fopen("input.txt", "r")) == NULL) {
        printf("Error! opening file");
        exit(1);}
    }
    else{
        fp = fopen(argv[1], "r");
        }

    if (pipe(pipeFD) == -1){    /* creates a pipe */
    fprintf(stderr, "\nERROR: pipe() failed\n");
    exit(1);}

    file_log=fopen("file.log","w+"); /*open the log file*/

    pid=fork();
    if(pid==0) {//child process
    printf ("%d starts \n", getpid());
    close(pipeFD[0]);//close read end for child
    read_input(fp);
    return 0;
    exit(status);
    }else{//parent 
    double speed_read;
    close(pipeFD[1]);//close write end for parent
    while(1){
        if (read(pipeFD[0], &speed_read, sizeof(speed_read)) >0){
        if (speed_read<0)
        break;
        fprintf(file_log, "%f \n", speed_read); 
        printf("process %d received %f from child \n",getpid(),speed_read);
        }else
            printf("Nothing there to read \n");  
        }
    printf("parent ended \n");
    wait(&status);
    fclose(fp);
    fclose(file_log);
    }
    return 0;
}

void read_input(FILE *fp){
    char *line = NULL;
    double speed;
    int i=0; size_t len = 0; double exit_sign =-10.0;
    while(getline(&line, &len, fp) != -1) { 
        speed=atof(line);
        i++;
        if(i>MAX_I){//reads up to MAX_I rows of input
                        printf("I'll send the exit sign to parent now\n");
                        write(pipeFD[1], &exit_sign, sizeof(double));
                        free(line);
                        break;      
                    }
        if(write(pipeFD[1], &speed, sizeof(double)>0)){
            printf("%d at %d wrote that speed is %f\n",getpid(), i,speed);
        }else{printf("Write on pipe failed\n");}
        sleep(delay);
        }
    free(line);
}

這是打印的內容:


15032開始

15032 在 1 寫道,速度是 0.345670

進程 15031 從孩子那里收到 0.000000

15032 at 2 寫道速度是 12.678890

進程 15031 從孩子那里收到 0.000000

15032 at 3 寫道,速度是 34.789870

進程 15031 從孩子那里收到 0.000000

15032 在 4 寫道,速度是 0.000000

進程 15031 從孩子那里收到 0.000000

15032 at 5 寫道,速度是 12.009288

進程 15031 從孩子那里收到 0.000000

我現在將退出標志發送給家長

父母結束


同樣,日志文件包含以下內容:

0.000000

0.000000

0.000000

0.000000

0.000000

read_input行中:

 if(write(pipeFD[1], &speed, sizeof(double)>0)){

一定是

if(write(pipeFD[1], &speed, sizeof(double))>0){

在您的情況下,您不寫sizeof(double)字節,而只寫 1

注意read_input做了兩次free(line); 對於未定義的行為,您必須在if(i>MAX_I){時刪除該行為

更正、編譯和執行后:

pi@raspberrypi:/tmp $ gcc -g -Wall p.c
pi@raspberrypi:/tmp $ cat input.txt 
1.2
2.3
3.45
7.8
9.12
12.345
pi@raspberrypi:/tmp $ ./a.out
15121 starts 
15121 at 1 wrote that speed is 1.200000
process 15120 received 1.200000 from child 
15121 at 2 wrote that speed is 2.300000
process 15120 received 2.300000 from child 
15121 at 3 wrote that speed is 3.450000
process 15120 received 3.450000 from child 
15121 at 4 wrote that speed is 7.800000
process 15120 received 7.800000 from child 
15121 at 5 wrote that speed is 9.120000
process 15120 received 9.120000 from child 
I'll send the exit sign to parent now
parent ended 
pi@raspberrypi:/tmp $ cat file.log
1.200000 
2.300000 
3.450000 
7.800000 
9.120000 
pi@raspberrypi:/tmp $ 

當您檢測到 EOF 並執行printf("Nothing there to read \n"); break; 完成while似乎更好。 請注意,當您到達read_input 中的輸入文件末尾時,您也可以發送 exit_sign 如果您不這樣做,如果輸入文件的行少於MAX_I


A pipe is a stream but reading or writing pipe data is atomic if the size of data written is not greater than PIPE_BUF where PIPE_BUF is at least 512 bytes, and 4096 under Linux

因此,在您的主要情況下,您盡可能快地讀取並且read_input function 休眠,而您讀取和寫入相同的少量字節,您沒有風險。 否則,通常當您讀取 stream 時,您需要循環直到獲得預期的字節數,例如通過調用 function 來替換read的使用,例如:

int read_block(int f, char * p, size_t sz)
{
  ssize_t n;

  while ((n = read(f, p, sz)) > 0) {
    if ((sz -= (size_t) n) == 0)
      return 1;
    p += n;
  }

  return -1;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM