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

时间:2018-12-16 10:34:49

标签: c pipe fork

我有一个创建2个子进程的程序。 Client进程将其PID发送到Server进程,Server进程将随机ID发送回Client进程,最后,Client进程收到ID并打印出来。

我的代码中的问题是我无法正确获得执行顺序。我可以做一个Client-Client-Server或Server-Client-Client通信。 如何强制程序以正确的顺序执行?

我正在尝试模拟这种Client-Server通信,以便以后将其扩展到与单个Server通信的多个Client,因此原始过程不应包含在解决方案中。

感谢您的帮助。

当前输出:

Client(2971):从服务器上获取了新的ID 32767。

服务器(2972):从客户端获取了pid 2971。正在发送新的ID。

预期输出:

服务器(2972):从客户端获取了pid 2971。正在发送新的ID。

Client(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);
}

1 个答案:

答案 0 :(得分:0)

尽管我没有运行您的代码,但是您的代码中有3个进程。

  Main process
  |         |
  |         |
  v         v
Server    Child
  

经验法则:即使您确定子进程在父进程之前结束,也不要忘记执行埋葬程序。通过调用wait(...),您告诉操作系统我已经为孩子完成了工作,因此现在您可以清除分配的字段等。

因此,您必须等待两个孩子都等待主进程返回。如果没有机会开始执行服务器进程或客户端进程怎么办?僵尸?孤儿?

AFAIS,如果我们忽略上述情况,我认为您的程序可以正常工作。不按顺序打印并不表示它工作不正常。您无法代表OS决定先运行哪个进程,等等,除非您可以分别通过关键部分或中断概念(如信号量或信号发送)​​将感觉敲入。