我正在尝试编写一个服务器程序,该程序会分叉处理多个客户端连接,从而为每个连接创建一个线程。但是这个进程可以创建的最大线程数永远不会超过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字节。 –