在子进程处理请求之后,就不支持 ab 压测了?

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <signal.h>
#include <string.h>
   
#define SERV_PORT 8031
  
int main(void)
{
    int lfd, cfd;
    struct sockaddr_in serv_addr,clin_addr;
    socklen_t clin_len;
    pid_t pid;
    char buf[1024];
    int len;
   
    if((lfd = socket(AF_INET,SOCK_STREAM,0)) == -1){
        perror("create socket failed");
        exit(1);
    }
 
    int opt = 1;
    setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
     
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(SERV_PORT);
      
    if(bind(lfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1)
    {
        perror("bind error");
        exit(1);
    }
       
    if(listen(lfd, 128) == -1)
    {
        perror("listen error");
        exit(1);
    }
  
    clin_len = sizeof(clin_addr);
 
    signal(SIGCLD,SIG_IGN);
 
    while(1)
    {
         
        if((cfd = accept(lfd, (struct sockaddr *)&clin_addr, &clin_len)) == -1)
        {
            perror("accept error");
            exit(1);
        }
 
        pid = fork();
 
        if (pid > 0)
        {
            // 在父进程中关闭连接的套接字描述符,只是把 cfd 的引用数减少1,在子进程中还在使用 cfd
            close(cfd);
        }
        else if (pid == 0)
        {
            // 子进程关闭 lfd 处理任务,使其回到 TIME_WAIT 状态值
            close(lfd);
 
            char web_result[] = "HTTP/1.1 200 OK\r\nContent-Type:text/html\r\nContent-Length: 11\r\nServer: mengkang\r\n\r\nhello world";
            write(cfd,web_result,sizeof(web_result));
 
            close(cfd);
            exit(0);
        }
        else
        {
            perror("fork error");
            exit(1);
        }
 
    }
  
    close(lfd);
      
    return 0;
}

如果对上面的代码 ab 测试,不管多少个请求,多少并发都不行

[root@localhost ~]# ab -c1 -n1 http://127.0.0.1:8031/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
 
Benchmarking 127.0.0.1 (be patient)...apr_socket_recv: Connection reset by peer (104)

直接在浏览器上访问是没问题的,怎么回事呢?是不是我某个地方写的不严谨,不符合规范?
如果把上面的代码中的多线程去掉,就能够使用 ab 了。

回复
阅读 2.5k
3 个回答

问题我找到了,原来是我在子进程了没有多cfd(client socket fd)执行read 操作。很诡异,在单一线程循环服务器的时候不读取则没事。http://mengkang.net/573.html

fork多进程是不可以运行在cgi模式下的。 (php是这样, c语言应该也是这样)

代码没有太大的问题呀
是不是 ab 测试的时候fork出的的进程太多(fork的效率也很低,用vfork代替),导致系统kill掉了这个进程树

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏