在Linux中,流套接字服务器不能处理超过382个线程(每个连接一个)

时间:2021-12-13 21:02:46

I am trying to write a server program which forks a process for handling multiple client connections which creates one thread per connection. But the maximum number of threads this process can create never exceeds 382.

我正在编写一个服务器程序,它为处理多个客户端连接提供一个进程,每个连接创建一个线程。但是这个进程可以创建的线程的最大数量永远不会超过382。

Why can't I create more number of threads which handle one file descriptor for communicating with one client while the file descriptor limit per process is 1024 in Linux?

为什么我不能创建更多的线程来处理一个文件描述符来与一个客户端通信,而在Linux中每个进程的文件描述符限制是1024 ?

I'm using a system running Kubuntu on Core-i3 with 2GB ram.

我正在使用一个在Core-i3上运行Kubuntu的系统,它有2GB的内存。

Here is the code for main function..

这是主函数的代码。

int server_start(void)
{
listen(skid,10000);
scnt=0;
printf("Server Listening at port:%d\n",serdt.port);
for(scnt=0;scnt<1000;)
{
        sdata->cpid[scnt]=fork();
        switch(sdata->cpid[scnt])
        {
            case -1:    printf("Could not Fork\n"); break;
            case  0:    mxsubserver(scnt); exit(0);
            default:    scnt++; break;
        }
//  }
    //check for other parameters
    pause();
}
while(1);
}

Variable not declared in the function are global variables. I have a blank action handler for signal number 50 for breaking out of the pause.

函数中未声明的变量是全局变量。我有一个空白的动作处理程序,用于第50号信号,用于跳出暂停。

The forked process sends the signal to the parent(this) process when the limit(file descriptor) is reached and then it will fork a new process. Below is the server process code called after fork in above code...

当到达极限(文件描述符)时,分叉进程将信号发送给父进程(此进程),然后它将分叉一个新的进程。下面是上面代码中在fork之后调用的服务器进程代码……

typedef struct
{
    int cln;
    int cnt;
    int fd;
    pthread_t ptid;
}service_d;

void mxsubserver(int cln)
{//cln is the child sub-server number
int ln,fd,rfp;
pthread_t ptid;
pthread_attr_t attr;
iflag=1;

sub_data = shmat(shmid,NULL,SHM_RND);

signal(SIGINT,sub_sigint);
signal(SIGPIPE,sub_sigpipe);
signal(50,SIG_DFL);
parg = malloc(sizeof(service_d));
parg->cln = cln;
cnt=0;
printf("Server Instance %d Started\n",cln);
for(cnt=0;;)
{
    if(iflag)
    {
        cnt++;
        ln = (socklen_t)sizeof(struct sockaddr_in);
        fd = accept(skid,(struct sockaddr *)&sktaddr,&ln);
        parg->fd=fd;
        parg->cnt=(cln*1000)+cnt;
        pthread_attr_init(&attr);
        pthread_create(&(parg->ptid),&attr,&service,parg);
        pthread_detach(parg->ptid);
        pthread_attr_destroy(&attr);
        sub_data->openfd[cln]=cnt;
    }
    if(cnt>=1000)
    {
        printf("Limit Reached\n");
        iflag=getppid();
        printf("Signalling Parent\n");
        kill(iflag,50);
        iflag=0;
        pause();
    }
    if(cnt==0)
    {
        free(parg);
        exit(0);
    }
}
kill(getppid(),50);
while(1);
return;
}
void sub_sigint(int sn)
{
free(parg);
shmdt(sub_data);
exit(0);
}

void sub_sigpipe(int sn)
{
cnt--;
iflag=1;
}

void* service(void *arg)
{//handle the client requests
int fd,cln,l,ol;
char im[100],*msg="This is from Server\n";
service_d *srd;

srd = (service_d*)arg;
//pthread_detach(srd->ptid);
fd = srd->fd;
cln = srd->cnt;
printf("service cln: %d f: %d\n",cln,iflag);
ol=strlen(msg);

while(1)
{
    read(fd,&l,sizeof(int)); //open to get sigpipe error if client closes
    if(read(fd,im,l)<0) break;
    im[l]='\0';
//  printf("Server %d thread %d: Got >> %s\n",srd->cln,cln,im);
    if(write(fd,&ol,sizeof(int))<0) break;
    if(write(fd,msg,ol)<0) break;;
}
close(fd);
pthread_exit("Done\n");
}

Thanks.

谢谢。

1 个解决方案

#1


3  

Solved it.

解决它。

Saw this thread: Threads/Sockets limits in Linux

看到这个线程:Linux中的线程/套接字限制

The default stack size is 8MB. When I create 382 threads, total size of the stacks created for all the threads is 8x382 i.e, around 3GB.

默认堆栈大小是8MB。当我创建382个线程时,为所有线程创建的堆栈的总大小是8x382 I。e,3 gb。

Therefore I reduced the stack size to 30KB using pthread_attr_setstacksize. Now after connecting to around 6000 clients it must say something like libgcc_s.so.1 must be installed for pthread_cancel to work . This can be solved by running the command: apt-get install libgcc1-dbg as root.

因此,我使用pthread_attr_setstacksize将堆栈大小减少到30KB。在连接到大约6000个客户机之后,它必须声明类似libgcc_s.so的内容。必须为pthread_cancel安装1才能工作。这可以通过运行命令来解决:apt-get安装libgcc1-dbg作为根。

#1


3  

Solved it.

解决它。

Saw this thread: Threads/Sockets limits in Linux

看到这个线程:Linux中的线程/套接字限制

The default stack size is 8MB. When I create 382 threads, total size of the stacks created for all the threads is 8x382 i.e, around 3GB.

默认堆栈大小是8MB。当我创建382个线程时,为所有线程创建的堆栈的总大小是8x382 I。e,3 gb。

Therefore I reduced the stack size to 30KB using pthread_attr_setstacksize. Now after connecting to around 6000 clients it must say something like libgcc_s.so.1 must be installed for pthread_cancel to work . This can be solved by running the command: apt-get install libgcc1-dbg as root.

因此,我使用pthread_attr_setstacksize将堆栈大小减少到30KB。在连接到大约6000个客户机之后,它必须声明类似libgcc_s.so的内容。必须为pthread_cancel安装1才能工作。这可以通过运行命令来解决:apt-get安装libgcc1-dbg作为根。