opricnik
opricnik

Reputation: 23

FIFO in While loop stucks and waits for read

Server sends its PID to client, client gets and sends SIGUSR1 signal in a loop, so i have handler for that in server code. In theory it needs to get signal and create some random matrix to client back.Client receives Server PID but it never sends matrix to client for some reason. It waits and insert blinking forever.I assume somehow they dont connect to each other but why? I tried to sending a matrix and it did just fine.

client.c

int main()
{
    int n=2;
      pid_t pid=1;
      int i,j;
      double matrix[20][20];
   char *myfifo2 = "/tmp/kek_fifo";
       int server_to_client;
   char *myfifo3 = "/tmp/fifor_fifo";
       int fifor;
       int forke=1;

   char str[BUFSIZ];
     fifor = open(myfifo3, O_RDONLY);
        read(fifor,&pid,sizeof(pid));
        printf("pid %d\n",pid);

   close(fifor);
    unlink(myfifo3);



 while(1){
      printf("no\n");
      server_to_client = open(myfifo2, O_RDONLY);
      read(server_to_client,matrix,sizeof(matrix));
      close(server_to_client);
      printf("yes\n");
    forke=fork();
    if(forke){

        printf("forke buyuktur >= parent olmali %d \n",forke);
     for(i = 0; i < 2*n; i++){
        for(j = 0; j < 2*n; j++){
            printf("%2f ",matrix[i][j]);
        }
        printf("\n");
    }
        wait(0); //parent child bekliyo 
    }

    else{
        printf("forke =0  yani child %d \n",forke);

        exit(0);
    }
        //sleep(5);
       kill(pid,SIGUSR1);


    }   


   return 0;
}

server.c

void actionHandler(int signum);
void matrix_init(double m[20][20],int n);
void randome(double myPointer[20][20],int n);

static int signalcheck=0;
int main()
{
   int i,j;
      int n=2; //argv olacak
      pid_t pide=getpid();
      printf("pide is %d \n",pide);
       struct sigaction action;
       action.sa_handler=actionHandler; 
       action.sa_flags = 0;

   int client_to_server;
   char *myfifo = "/tmp/client_to_server_fifo";
   int forke;
   int server_to_client;
   char *myfifo2 = "/tmp/kek_fifo";
   char *myfifo3 = "/tmp/fifor_fifo";
   int fifor;
   char buf[BUFSIZ];
   double M[20][20];
    matrix_init(M,n);

   /* create the FIFO (named pipe) */
 //  mkfifo(myfifo, 0666);
  mkfifo(myfifo2, 0666);
   mkfifo(myfifo3,0666);

   fifor =open(myfifo3,O_WRONLY);
   write(fifor,&pide,sizeof(pide));
   close(fifor);
   unlink(myfifo3);

   if ((sigemptyset(&action.sa_mask) == -1) ||
      (sigaction(SIGUSR1, &action, NULL) == -1))
      perror("Failed to install SIGURS1 signal handler");

   /* open, read, and display the message from the FIFO */
  // client_to_server = open(myfifo, O_RDONLY);


   printf("Server ON.\n");

   while (1)
   {



   if(signalcheck==1){

   forke=fork();
   if(forke==0){
      while(1){
         randome(M,n);

         server_to_client = open(myfifo2, O_WRONLY);
         write(server_to_client,M,sizeof(M));
         close(server_to_client);
         unlink(myfifo2);
         printf("matrix yarat\n");
         //sleep(5);
         //create matrix send to fifo 
      }
   }
      /*
      read(client_to_server, buf, BUFSIZ);

      if (strcmp("exit",buf)==0)
      {
         printf("Server OFF.\n");
         break;
      }

      else if (strcmp("",buf)!=0)
      {
         printf("Received: %s\n", buf);
         printf("Sending back...\n");
         write(server_to_client,buf,BUFSIZ);
      }

       clean buf from any data 
      memset(buf, 0, sizeof(buf)); */
         //sleep(5);
   }
   signalcheck=0;
   }

 //  close(client_to_server);
 //  close(server_to_client);
// unlink(myfifo);
  // unlink(myfifo2);
   return 0;
}
 void actionHandler(int signum)
{
    signalcheck=1;
      if(signum==SIGUSR1)
         printf("i catched signal code from client  i guess \n");
    /* Signal handler code goes here. */

}


void matrix_init(double m[20][20],int z){
    /* 
    this function purpose to create
    2Nx2N int matrix n being int z
    then initing this matrix to 0 before random numbers take in part
    it has error checks .
    blah!*/
    int i, j,n=z;
    double **k = (double **) malloc(n * sizeof(double*));

    if(m == NULL){
        printf("Error full matrix not created");
        exit(-1);
    }

    for(i = 0; i < n; i++){
        for(j = 0; j < n; j++){
            m[i][j] = 0;
        }
    }

}


 void randome(double  myPointer[20][20],int n){
    int i,j;
    int r;
    srand ( time(NULL) );
    for(i=0;i<n*2;i++)
        for(j=0;j<n*2;j++)
            myPointer[i][j]=rand()%10;
 }

Upvotes: 1

Views: 451

Answers (1)

Jonathan Leffler
Jonathan Leffler

Reputation: 753475

I think one reason your question got ignored for so long is that the code is that there's quite a lot of code and a fair amount of comments that are irrelevant bits of code, and the layout isn't all tidy. These add up to "it is hard work to read the code", which puts people off actually reading it.

This code seems to work OK on a MacBook Pro running macOS Sierra 10.12.4 using GCC 6.3.0 to compile.

Client code

#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

int main(void)
{
    int n = 2;
    pid_t pid = 1;
    int i, j;
    double matrix[20][20];
    char *myfifo2 = "/tmp/kek_fifo";
    int server_to_client;
    char *myfifo3 = "/tmp/fifor_fifo";
    int fifor;
    int forke = 1;

    fifor = open(myfifo3, O_RDONLY);
    read(fifor, &pid, sizeof(pid));
    printf("pid %d\n", pid);

    close(fifor);
    unlink(myfifo3);

    for (int loopnum = 0; loopnum < 20; loopnum++)
    {
        printf("begin loop %d\n", loopnum);
        kill(pid, SIGUSR1);
        printf("signal sent\n");
        server_to_client = open(myfifo2, O_RDONLY);
        printf("Open done\n");
        read(server_to_client, matrix, sizeof(matrix));
        printf("read done\n");
        close(server_to_client);
        printf("close done\n");
        forke = fork();
        if (forke)
        {
            printf("forke buyuktur >= parent olmali %d\n", forke);
            for (i = 0; i < 2 * n; i++)
            {
                for (j = 0; j < 2 * n; j++)
                {
                    printf("%2f ", matrix[i][j]);
                }
                printf("\n");
            }
            wait(0); // parent child bekliyo
        }
        else
        {
            printf("forke = 0  yani child %d\n", forke);
            exit(loopnum);
        }
    }

    return 0;
}

Server code

#include <assert.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>

void actionHandler(int signum);
void matrix_init(double m[20][20], int n);
void randome(double myPointer[20][20], int n);

static volatile sig_atomic_t signalcheck = 0;

int main(void)
{
    int n = 2; // argv olacak
    pid_t pide = getpid();
    printf("pide is %d\n", pide);
    struct sigaction action;
    action.sa_handler = actionHandler;
    action.sa_flags = 0;

    int forke;
    int server_to_client;
    char *myfifo2 = "/tmp/kek_fifo";
    char *myfifo3 = "/tmp/fifor_fifo";
    int fifor;
    double M[20][20];
    matrix_init(M, n);
    srand(time(NULL));

    if ((sigemptyset(&action.sa_mask) == -1) ||
        (sigaction(SIGUSR1, &action, NULL) == -1))
    {
        perror("Failed to install SIGURS1 signal handler");
        return 1;
    }

    /* create the FIFO (named pipe) */
    mkfifo(myfifo2, 0666);
    mkfifo(myfifo3, 0666);

    fifor = open(myfifo3, O_WRONLY);
    write(fifor, &pide, sizeof(pide));
    close(fifor);
    unlink(myfifo3);

    printf("Server ON (%d).\n", signalcheck);

    while (1)
    {
        if (signalcheck == 1)
        {
            printf("Signal received:\n");
            signalcheck = 0;
            randome(M, n);
            forke = fork();
            if (forke == 0)
            {
                    server_to_client = open(myfifo2, O_WRONLY);
                    write(server_to_client, M, sizeof(M));
                    close(server_to_client);
                    printf("matrix yarat %d\n", (int)getpid());
                    exit(0);
            }
            else
            {
                int corpse;
                int status;
                while ((corpse = wait(&status)) != -1)
                    printf("PID %d exited with status 0x%.4x\n", corpse, status);
            }
        }
    }

    return 0;
}

void actionHandler(int signum)
{
    static char msg[] = "I caught a signal from the client\n";
    signalcheck = 1;
    if (signum == SIGUSR1)
    {
        int nb = write(1, msg, sizeof(msg)-1);
        assert(nb == sizeof(msg)-1);
    }
}

void matrix_init(double m[20][20], int z)
{
    for (int i = 0; i < z; i++)
    {
        for (int j = 0; j < z; j++)
            m[i][j] = 0;
    }
}

void randome(double myPointer[20][20], int n)
{
    int i, j;
    for (i = 0; i < n * 2; i++)
    {
        for (j = 0; j < n * 2; j++)
            myPointer[i][j] = rand() % 10;
    }
}

Server output

pide is 474
Server ON (0).
I caught a signal from the client
Signal received:
matrix yarat 476
PID 476 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 478
PID 478 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 481
PID 481 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 483
PID 483 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 485
PID 485 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 488
PID 488 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 491
PID 491 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 493
PID 493 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 496
PID 496 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 499
PID 499 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 501
PID 501 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 503
PID 503 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 506
PID 506 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 512
PID 512 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 514
PID 514 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 516
PID 516 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 518
PID 518 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 521
PID 521 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 523
PID 523 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 525
PID 525 exited with status 0x0000
^C

The ^C is where I interrupted the server in its terminal window. The program was spinning in a busy loop, using 99.5% of a CPU.

Client output

pid 474
begin loop 0
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 477
5.000000 6.000000 0.000000 9.000000 
2.000000 1.000000 4.000000 7.000000 
0.000000 8.000000 2.000000 5.000000 
7.000000 8.000000 3.000000 2.000000 
forke = 0  yani child 0
begin loop 1
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 480
0.000000 7.000000 0.000000 3.000000 
0.000000 7.000000 2.000000 9.000000 
2.000000 4.000000 5.000000 5.000000 
9.000000 7.000000 3.000000 4.000000 
forke = 0  yani child 0
begin loop 2
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 482
8.000000 6.000000 1.000000 4.000000 
9.000000 2.000000 3.000000 9.000000 
2.000000 3.000000 8.000000 0.000000 
7.000000 8.000000 9.000000 8.000000 
forke = 0  yani child 0
begin loop 3
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 484
1.000000 4.000000 2.000000 9.000000 
5.000000 3.000000 5.000000 0.000000 
5.000000 9.000000 7.000000 5.000000 
3.000000 1.000000 7.000000 3.000000 
forke = 0  yani child 0
begin loop 4
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 487
2.000000 3.000000 0.000000 4.000000 
0.000000 2.000000 6.000000 8.000000 
1.000000 8.000000 8.000000 7.000000 
7.000000 4.000000 1.000000 4.000000 
forke = 0  yani child 0
begin loop 5
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 489
6.000000 3.000000 4.000000 0.000000 
5.000000 9.000000 2.000000 3.000000 
9.000000 7.000000 5.000000 4.000000 
5.000000 9.000000 1.000000 8.000000 
forke = 0  yani child 0
begin loop 6
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 492
7.000000 1.000000 4.000000 6.000000 
7.000000 1.000000 2.000000 4.000000 
5.000000 1.000000 8.000000 6.000000 
1.000000 9.000000 8.000000 6.000000 
forke = 0  yani child 0
begin loop 7
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 495
0.000000 0.000000 5.000000 1.000000 
6.000000 8.000000 3.000000 1.000000 
8.000000 1.000000 6.000000 9.000000 
7.000000 3.000000 1.000000 5.000000 
forke = 0  yani child 0
begin loop 8
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 497
3.000000 0.000000 1.000000 8.000000 
4.000000 4.000000 2.000000 3.000000 
8.000000 9.000000 6.000000 3.000000 
1.000000 3.000000 6.000000 3.000000 
forke = 0  yani child 0
begin loop 9
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 500
4.000000 0.000000 9.000000 3.000000 
1.000000 5.000000 1.000000 2.000000 
3.000000 0.000000 5.000000 6.000000 
4.000000 5.000000 9.000000 7.000000 
forke = 0  yani child 0
begin loop 10
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 502
4.000000 9.000000 7.000000 6.000000 
6.000000 4.000000 7.000000 1.000000 
3.000000 5.000000 9.000000 0.000000 
7.000000 9.000000 7.000000 9.000000 
forke = 0  yani child 0
begin loop 11
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 504
3.000000 3.000000 0.000000 3.000000 
7.000000 5.000000 8.000000 5.000000 
6.000000 1.000000 3.000000 6.000000 
8.000000 3.000000 3.000000 0.000000 
forke = 0  yani child 0
begin loop 12
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 507
6.000000 5.000000 1.000000 8.000000 
7.000000 3.000000 9.000000 7.000000 
9.000000 4.000000 0.000000 5.000000 
1.000000 6.000000 9.000000 3.000000 
forke = 0  yani child 0
begin loop 13
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 513
6.000000 4.000000 6.000000 3.000000 
5.000000 6.000000 6.000000 0.000000 
2.000000 1.000000 5.000000 2.000000 
7.000000 3.000000 9.000000 8.000000 
forke = 0  yani child 0
begin loop 14
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 515
0.000000 3.000000 7.000000 8.000000 
9.000000 1.000000 2.000000 4.000000 
5.000000 7.000000 4.000000 8.000000 
3.000000 1.000000 1.000000 6.000000 
forke = 0  yani child 0
begin loop 15
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 517
0.000000 8.000000 9.000000 7.000000 
7.000000 3.000000 3.000000 0.000000 
4.000000 0.000000 8.000000 1.000000 
5.000000 8.000000 4.000000 4.000000 
forke = 0  yani child 0
begin loop 16
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 520
8.000000 3.000000 8.000000 8.000000 
1.000000 7.000000 0.000000 3.000000 
4.000000 2.000000 0.000000 3.000000 
8.000000 4.000000 4.000000 8.000000 
forke = 0  yani child 0
begin loop 17
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 522
9.000000 3.000000 9.000000 3.000000 
3.000000 3.000000 2.000000 9.000000 
9.000000 3.000000 6.000000 0.000000 
8.000000 0.000000 8.000000 1.000000 
forke = 0  yani child 0
begin loop 18
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 524
9.000000 1.000000 4.000000 3.000000 
4.000000 8.000000 9.000000 2.000000 
2.000000 5.000000 0.000000 6.000000 
9.000000 0.000000 5.000000 7.000000 
forke = 0  yani child 0
begin loop 19
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 526
2.000000 0.000000 5.000000 3.000000 
1.000000 2.000000 1.000000 3.000000 
3.000000 6.000000 5.000000 8.000000 
7.000000 3.000000 2.000000 5.000000 
forke = 0  yani child 0

Note that the client exited tidily after 20 loops; it should probably have been smaller.

Some of the changes

  • The code only calls srand() once
  • The code sets up the servers signal handler before messing with the FIFOs.
  • The code no longer deletes the FIFO in a loop.
  • The code no longer sets signalcheck to zero unless it was one. One problem seemed to be that the 'signalcheck` variable was zero whenever checked.
  • The code uses static volatile sig_atomic_t signalcheck.
  • The random matrix is generated before the fork() so that different results are seen.
  • The server cleans up dead children (zombies).
  • It really isn't clear why either the server or the child forks, but that was left more or less as found.
  • The signal handler doesn't use printf().

Improvements still needed

The code is far from perfect. There are multiple things that should be addressed, including:

  • Handling errors correctly (e.g. after fork() in server).
  • Mechanism to terminate server other than interrupt.
  • Detecting when client has stopped.
  • Not using signals to tell the server there is work.
  • Removing client forking.
  • Decide whether server really needs to fork.
  • Use configurable FIFO names.
  • Sort out matrix initialization better.
  • Etc.

Upvotes: 1

Related Questions