简体   繁体   English

在父进程和子进程之间进行Fork()切换

[英]Fork() switch between Parent and Child processes

I have a program that creates 2 child processes. 我有一个创建2个子进程的程序。 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. 客户端进程将其PID发送到服务器进程,服务器进程将随机ID发送回客户端进程,最后,客户端进程接收ID并将其打印出来。

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. 我可以做一个Client-Client-Server或Server-Client-Client通信。 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. 客户端(2971):从服务器检索到新的ID 32767。

Server(2972): Recived pid 2971 from client. 服务器(2972):从客户端检索到pid 2971。 Sending new ID. 正在发送新的ID。

Expected Output: 预期产量:

Server(2972): Recived pid 2971 from client. 服务器(2972):从客户端检索到pid 2971。 Sending new ID. 正在发送新的ID。

Client(2971): Recieved new ID 32767 from Server. 客户端(2971):从服务器检索到新的ID 32767。

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. 尽管我尚未运行您的代码,但是您的代码中有3个进程。

  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. 通过调用wait(...)您告诉操作系统我已经为孩子完成了工作,因此现在您可以清理分配的字段等。

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. AFAIS,如果我们忽略上述情况,我认为您的程序可以按预期运行。 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. 您无法代表OS决定先运行哪个进程,等等,除非您可以分别通过关键部分或中断概念(如信号量或信号发送)​​将感觉敲入。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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