读取后 FIFO 管道内容包含错误的字符

FIFO pipe content contains wrong chars after read

我创建了一个程序,它在 10 个线程上并行查找整数数组中的最大值,并且有一个 parent 和一个 child 进程。 Child 计算区间的最大值(数组有 1000 个元素)最大值并写入命名管道,parent 只是从 FIFO 中读取最大值并打印它。当我想从 FIFO 中读取内容时,读取的内容包含一些错误的字符,但输入的字符串是正确的。 我怎样才能避免这个问题?

我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/wait.h>

#define max 1000

#define Th_max 10

int numbers[max];

int max_num[Th_max] = { 0 };
int thread_no = 0;

void *maximum(void* arg)
  ....
}

int main()
{
    int maxs = 0;
    int i;
    char buf[32];
    int fd, ret;
    int pipefd[2];  
     pid_t cpid;
    pthread_t threads[Th_max];

    srand(time(0));
    for( i = 0; i < 1000; i++ ) {
        numbers[i] = rand();
   }
    cpid = fork();
    if (cpid == -1) {
       perror("fork");
       exit(-1);
    }
    if (cpid == 0) {
        printf("PID: %d : Child process \n",getpid());

        for (i = 0; i < Th_max; i++)
            pthread_create(&threads[i], NULL,
                        maximum, (void*)NULL);



        for (i = 0; i < Th_max; i++)
            pthread_join(threads[i], NULL);


        for (i = 0; i < Th_max; i++) {
            if (max_num[i] > maxs)
                maxs = max_num[i];
        }   
        fd=open("Pipe",O_RDWR);
        
        sprintf(buf, "%d", maxs);
        printf("PID: %d :Write this to FIFO: %s:%ld\n",getpid(),buf,strlen(buf));
        write(fd,buf,strlen(buf)); 

        exit(0);
        
        
     } else {
           printf("PID: %d : Parent process\n",getpid());

           ret=mkfifo("Pipe",00666);    
           if (ret == -1) {
               perror("mkfifo()");
               exit(-1);
            }

           fd=open("Pipe",O_RDWR);
           if (fd == -1) {
               perror("open() error!");
               exit(-1);
            }


            wait(NULL);   
            ret=read(fd,buf,32); 
            printf("PID: %d :Read %d byte: %s\n",getpid(),ret,buf);

            close(fd);
            
            unlink("LA3WXZ");   
    }


    return 0;
    
}

OP 的代码试图将字符数组打印为 字符串 。它不是所需的 字符串 ,因为它在第 10 个字符后缺少 空字符 ..

改为使用 精度 来限制字符数组的打印。

//printf("PID: %d :Read %d byte: %s\n",getpid(),ret,buf);
printf("PID: %d :Read %d byte: %.*s\n",getpid(),ret, ret, buf);
//                              ^^                   ^^^ precision

或者最多只读少1个字符并追加0。

// ret=read(fd,buf,32); 
ret = read(fd, buf, sizeof buf - 1); 
if (ret >= 0) {
  buf[ret] = '[=11=]';
  ...

或发送空字符。

// write(fd,buf,strlen(buf));
write(fd,buf,strlen(buf) + 1);

或者...


注意:getpid() 不一定 return 和 intCast to a wide type 并打印。

printf("%lld\n", (long long) getpid());