简体   繁体   中英

Fork() switch between Parent and Child processes

I have a program that creates 2 child processes. The Client process sends it's PID to the Server process, the Server process sends a random ID back to the Client process, and finally, the Client process receives the ID and prints it.

The problem in my code is that I can't get the order of the execution correctly. I can either do a Client-Client-Server, or a Server-Client-Client communication. How can I force the program to execute in the correct order?

I'm trying to simulate this Client-Server communication to later scale it to multiple Clients communicating with a single Server so the original process shouldn't factor in the solution.

Thanks for your help.

Current Output:

Client(2971): Recieved new ID 32767 from Server.

Server(2972): Recived pid 2971 from client. Sending new ID.

Expected Output:

Server(2972): Recived pid 2971 from client. Sending new ID.

Client(2971): Recieved new ID 32767 from Server.

int main (int argc, char *argv[])
{
   int petitionPipe[2];
   int responsePipe[2];

if (pipe(petitionPipe) != 0 || pipe(responsePipe) != 0)
{
    err_exit("Failed to open a pipe\n");
}

int client = fork();
int server = 0;

if (client > 0)
{
    server = fork();
}

if (client < 0 || server < 0)
{
    err_exit("fork() failed\n");
}

else if (client == 0)
{
    clientPetition(petitionPipe, responsePipe);
}

else if (server == 0)
{
    serverResponse(petitionPipe, responsePipe);
}

if (client == 0)
{
    clientResult(petitionPipe, responsePipe);
}

return 0;


static void clientPetition(int *petitionPipe, int *responsePipe)
 {
    pid_t pid;

    close(petitionPipe[READ]);
    close(responsePipe[WRITE]);
    close(responsePipe[READ]);

    pid = getpid();

    write(petitionPipe[WRITE], &pid, sizeof(pid_t));
 }

static void serverResponse(int *petitionPipe, int *responsePipe)
 {
    pid_t pid;
    int newID;

    close(petitionPipe[WRITE]);
    close(responsePipe[READ]);

    read(petitionPipe[READ], &pid, sizeof(pid));

    printf("Server(%d): Recived pid %d from client. Sending new ID.\n\n", getpid(), pid);

    srand(pid);
    newID = rand() % 100;

    write(responsePipe[WRITE], &newID, sizeof(newID));
 }

static void clientResult(int *petitionPipe, int *responsePipe)
{
    int newID;

    close(petitionPipe[READ]);
    close(petitionPipe[WRITE]);
    close(responsePipe[WRITE]);

    read(responsePipe[READ], &newID, sizeof(newID));

    printf("Client(%d): Recieved new ID %d from Server.\n\n", getpid(), newID);
}

Though I've not run your code, there are 3 processes in your code.

  Main process
  |         |
  |         |
  v         v
Server    Child

Rule of thumb: Don't forget to carry burial procedures out even though you are sure that child process ends prior parent process. By invoking wait(...) you tell the operating system that I'm done my things for my child so now you can clean allocated fields etc.

So, you have to wait the both children before let the main process return. What if there is no chance to commence execution of server process or client process? Zombie?? Orphan??

AFAIS, If we ignore the aforementioned case, I think your program works as expected. Printing without order doesn't mean it works wrong. You cannot decide on behalf of OS which process runs first etc except you can knock sense them into via critical section or interruption concepts like semaphore or signaling, respectively.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM