1

I created a program which looking for a maximum in an integer array parallel on 10 thread and has a parent and a child process. Child calculate the maximum of interval's (array has 1000 elements) maximum and write to the named pipe, parent just reads the max number from the FIFO and print it. When I wanna read content from FIFO, the read content contains some wrong characters but the input string is ok. How can I avoid this problem?

enter image description here

My code:

#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;
    
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Cof
  • 47
  • 4

1 Answers1

3

OP's code is attempting to print an array of characters as a string. It is not the desired string as it lacks a null character after the 10th character..

Instead use a precision to limit printing a character array.

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

Or only read up to 1 less character and append a 0.

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

Or send the null character.

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

Or ...


Note: getpid() does not certainly return an int. Cast to a wide type and print.

printf("%lld\n", (long long) getpid());
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256