Sergio
Sergio

Reputation: 275

Parent not executing in an infinite loop

My goal from the code is the following:
-Generate a random number between a given range
-Make user guess the number using the child process.
-Make the parent tell the user if guess should be higher/lower.
-If guess is correct give a signal for the child to exit.

Current complete code:

int main() {

pid_t pid=fork();
int guess;

int* shared_values=mmap(NULL, 3*sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);


shared_values[0]= 1+ rand() % 51;
shared_values[2]=0;

if(pid<0){
    printf("Fork failed");
}

if(pid==0){
printf("Enter your guess: \n");
}

while(1)
{

if(pid==0){
    if(shared_values[2]==1)
        exit(0);

scanf("%d", &guess);
shared_values[1]=guess;

}

if(pid>0){

wait(NULL);
    if(shared_values[1]>shared_values[0]){
        printf("Guess should be lower");
    }

    if(shared_values[1]<shared_values[0]){
        printf("Guess should be higher");
    }

    if(shared_values[1]==shared_values[0]){
        printf("WIN");
        shared_values[2]=1;
        break;
    }

}
}
munmap(shared_values, 3*sizeof(int));
return 1;
}

I tried to put a printf before if(pid>0) and it printed once, tried to put it before wait(NULL) and it didn't execute so the parent is definitely not executing but why is that?

Upvotes: 0

Views: 88

Answers (2)

user3629249
user3629249

Reputation: 16540

the following proposed code:

  1. cleanly compiles
  2. performs the desired functionality
  3. has not been tested for 'race' conditions, I leave that up to the OP
  4. properly checks for I/O errors
  5. child properly notifies parent if a error occurs via -1 value
  6. only produces one shared memory segment
  7. properly handles all returned values from `fork()
  8. incorporates appropriate horizontal spacing for readability
  9. properly initializes the random number generator before calling rand()

and now, the proposed code:

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>


int main( void ) 
{
    srand( (unsigned)time( void );

    int* shared_values = mmap( NULL, 3*sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0 );

    if( (int)shared_values == -1 )
    {
        perror( "mmap failed" );
        exit( EXIT_FAILURE );
    }

    shared_values[0] = 1+ rand() % 51;
    shared_values[2] = 0;

    pid_t pid = fork();
    if( pid<0 )
    { // fork() error occurred
        perror( "Fork failed" );
        exit( EXIT_FAILURE );
    }

    if( pid==0 )
    { // child process
        int guess;
        while( 1 )
        {
            if( shared_values[2] == 1 )
            {
                exit( EXIT_SUCCESS );
            }

            printf("Enter your guess: \n");
            if( scanf( "%d", &guess ) != 1 )
            {
                fprintf( stderr, "scanf for guess failed\n" );
                shared_values[1] = -1;
                exit( EXIT_FAILURE );
            }

            shared_values[1] = guess;
        }  
    }

    // parent process
    while(1)
    {
        if( shared_values[1] == -1 )
        { // child failed
            break;
        }

        else if( shared_values[1] > shared_values[0] )
        {
            printf( "Guess should be lower\n" );
        }

        else if( shared_values[1] < shared_values[0] )
        {
            printf( "Guess should be higher\n" );
        }

        else if( shared_values[1] == shared_values[0] )
        {
            printf( "WIN\n" );
            shared_values[2] = 1;
            break;
        }
    }

    wait( NULL );
    munmap( shared_values, 3*sizeof(int) );
}

Upvotes: 1

A2020
A2020

Reputation: 86

If understand this correctly, the parent is waiting for the child process to exit before it verifies the answer, through the wait() call. But child process only exits if the answer was marked as correct by the parent process. Therefore the parent blocks on the wait() call and the child gets "feedback" from the parent.

Upvotes: 1

Related Questions