我正在嘗試編寫一個服務器程序,該程序會分叉處理多個客戶端連接,從而爲每個連接創建一個線程。但是這個進程可以創建的最大線程數永遠不會超過382.流式套接字服務器在Linux中無法處理超過382個線程(每個連接一個)
爲什麼我不能創建更多數量的線程來處理一個文件描述符與一個客戶端進行通信,而每個進程的文件描述符限制在Linux上是1024?
我使用的系統運行Kubuntu Core-i3與2GB RAM。
下面是主要功能的代碼..在功能上沒有聲明
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);
}
變量是全局變量。信號編號爲50的空白動作處理程序暫停了。
分叉進程在達到限制(文件描述符)時向父進程發送信號,然後分叉新進程。以下是在上面的代碼中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");
}
謝謝。
'/ proc/sys/kernel/pid_max'怎麼樣?和'/ proc/sys/kernel/threads-max'? – LPs
最有可能的是你遇到了某種資源限制,我懷疑堆棧大小的默認設置會佔用你的虛擬地址空間。 'ulimit -a'的堆棧大小告訴你什麼? – Art
pid_max是32768,thread_max是29138.堆棧大小是8192k字節。 –