【问题标题】:Multi-client socket programming zombie processes多客户端套接字编程僵尸进程
【发布时间】:2018-01-15 18:27:31
【问题描述】:

我希望使用fork() 系统调用实现到服务器的多客户端连接以传输一些数据。使用命令ps -a。我发现在我的客户端程序终止后,在服务器中创建的用于处理数据传输的子进程变成了僵尸进程(针对该进程显示<defunct>)。我知道父进程中的wait() 可能会解决问题,但我需要父进程中的while 循环连续运行以接受传入的客户端连接,并且不能等待子进程结束。请帮助我解决僵尸进程问题。我的服务器程序如下:

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include<string.h>

int main()
{
    int sock = 0;
    struct sockaddr_in addr;
    int addrlen = sizeof(addr);
    char buffer[1024] = {0};

    sock = socket(AF_INET, SOCK_STREAM, 0);
    addr.sin_family=AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons(2222);
    bind(sock, (struct sockaddr *)&addr, sizeof(addr));

    listen(sock,5);
    while(1)
    {
        int conn = accept(sock, (struct sockaddr *)&addr, (socklen_t *)&addrlen);
        int pid = fork();
        if(pid==0)
        {
            char buffer[1024] = {0};
            int readval = read(conn, buffer, 1024);
            printf("%s\n",buffer);
            break;
        }
        else if(pid < 0) printf("Process creation error");
    }

    close(conn);
    close(sock);

    return 0;
}

我的客户端程序如下:

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

int main()
{
    int sock = 0;
    struct sockaddr_in saddr;
    char msg[] = "Hello Server, this is Client 1";  

    sock = socket(AF_INET, SOCK_STREAM, 0);
    saddr.sin_family=AF_INET;
    saddr.sin_port = htons(2222);
    connect(sock, (struct sockaddr *)&saddr, sizeof(saddr));

    send(sock, msg, strlen(msg), 0);
    sleep(20);

    close(sock);

    return 0;
}

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

int main()
{
    int sock = 0;
    struct sockaddr_in saddr;
    char msg[] = "Hello Server, this is Client 2";  

    sock = socket(AF_INET, SOCK_STREAM, 0);
    saddr.sin_family=AF_INET;
    saddr.sin_port = htons(2222);
    connect(sock, (struct sockaddr *)&saddr, sizeof(saddr));

    send(sock, msg, strlen(msg), 0);
    sleep(20);

    close(sock);

    return 0;
}

【问题讨论】:

    标签: c sockets fork zombie-process


    【解决方案1】:

    有两种常见的避免僵尸的方法:

    1) 在主循环中使用非阻塞等待,例如 waitpid(-1, ..., WNOHANG)

    2) 安装一个 SIGCHLD 处理程序。当孩子退出时,它会异步调用,所以只需从那里等待。您甚至不必编写自己的处理程序,因为只需执行 signal(SIGCHLD, SIG_IGN) 就应该为您自动收割僵尸。请注意,如果您这样做,wait*() 函数将无法为您提供退出代码。

    【讨论】:

    • waitpid(-1, &status, WUNTRACED | WCONTINUED);为我工作
    猜你喜欢
    • 2022-01-10
    • 1970-01-01
    • 2014-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多