Stream Socket Server在Linux中不能处理超过382个线程(每个连接一个)

我正在尝试编写一个服务器程序,该程序分叉处理多个客户端连接,每个连接创build一个线程。 但是这个过程可以创build的线程的最大数量从来不会超过382。

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

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

这里是主要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); } 

未在函数中声明的variables是全局variables。 信号编号为50的空白行动处理程序暂停。

分叉进程在达到限制(文件描述符)时将信号发送给父(this)进程,然后分叉一个新进程。 下面是在上面的代码中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: %df: %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"); } 

谢谢。

解决了它。

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

默认的堆栈大小是8MB。 当我创建382个线程时,为所有线程创建的堆栈总大小为8×382,即大约3GB。

因此,我使用pthread_attr_setstacksize将堆栈大小减少到了30KB。 现在连接到大约6000个客户端之后,必须libgcc_s.so.1 must be installed for pthread_cancel to work一些类似libgcc_s.so.1 must be installed for pthread_cancel to work 。 这可以通过运行命令来解决: apt-get install libgcc1-dbg作为root用户。