【发布时间】:2017-08-08 20:22:25
【问题描述】:
这可能是与设置相关的问题。
问题:无法在我们的公共 Redhat 环境中生成超过 70 个 pthread。期望是几千。
附加的程序旨在向学生演示使用互斥信号量来控制对共享数据的访问,同时还展示了系统处理多于进程的 pthread 的能力。它是创建网络服务器程序教学单元的一部分。
不幸的是,该程序在大约 70 个 pthreads 时失败,这表明与我们系统上允许的并发进程数相同的限制,默认设置为 75。这发生在我们的两个企业学生环境中——一个是 Redhat 5.11,另一个是Redhat 6.8。这些是我们用来进行演示和学生做作业的共享环境。
在 Redhat 7 和 Ubuntu 15.04 的下载版本上,两者都在 VMWare 下运行,我能够生成数千个线程,这是我所期望的。
问题发生时,会在 main 中的初始 for 循环中变得明显。
/*
File: pthreadDemo2.c
Course: CENG320
Author: Prof. Leon King,J230,x4200
Date: Friday Jun 16, 2017 14:26 PM
In this demo we list the status of threads and selectively cancel them.
The commands are: list (list)
kill # kill a thread by number
inc have threads increment the counter
INC # increment a specific counter
quit end the program
show show the counter
Compile with the thread library -pthread
See also: http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
*/
#include <pthread.h>
#include <bits/local_lim.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
/* We have no predefined limit on the number of threads. */
#define NUMBER_OF_THREADS 4000
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER; //Warning! This is a shared global variable!
long counter=0;
void incrementCounter(int signum)
{
//pthread_mutex_lock(&mutex);
int c2;
c2=counter;
c2=c2+1;
counter=c2;
//fprintf(stdout,"Changing a counter\n");
/*FILE *log=fopen("threadSafeLog.dat","a");
fprintf(log,"Logging event for thread %u\n",(int) pthread_self());
fprintf(log,"Logging event 2nd write for thread %u\n",(int) pthread_self());
fclose(log);
*/
//pthread_mutex_unlock(&mutex);
}
void *threadProcedure(void * arg)
{
int myThreadInfo=(long) arg,
threadID=pthread_self();
while(1) pause();
pthread_exit(0); //calling exit() would end all threads & main
}
int main(int argc, char * argv[],char * envp[])
{
pthread_t threadList[NUMBER_OF_THREADS]={0};
char cmd[20];
pthread_mutex_init(&mutex,NULL);
pthread_attr_t threadAttributes;
pthread_attr_init(&threadAttributes);
int err1=pthread_attr_setstacksize(&threadAttributes, 16384);
if(err1) fprintf(stdout,"Error in setting the stack size: %d\n", err1);
signal(SIGUSR1,incrementCounter);
fprintf(stdout,"Hello World. I'm %d\n",(int) getpid());
//
//Spawn a group of threads
//THIS IS THE CORE OF THE PROBLEM
//IT CAN GENERATE OVER 6K threads on a Ubuntu 15.04 Release
//BUT only 70 threads on Redhat 5.11 and 6.8 Enterprise
//The focus question is: How does one increase the limit on the number of threads in Redhat
for(int i=0;i<NUMBER_OF_THREADS;i++)
{
if(!pthread_create(&threadList[i],&threadAttributes,threadProcedure,(void *)i))
{
pthread_detach(threadList[i]);
}
else perror("Failure to create a thread");
}
while(1)
{
fprintf(stdout,"Commands: list, show, increment, quit\n");
fscanf(stdin,"%s",cmd);
switch(cmd[0])
{
case 'l': for(int i=0;i<NUMBER_OF_THREADS;i++)
fprintf(stdout,"thread id of threadlist[%d]: %u\n",i,(int) threadList[i]);
break;
case 's': fprintf(stdout,"Counter value: %lu\n",counter);
break;
break;
case 'i': fprintf(stdout,"Initial value of counter: %lu\n",counter);
for(int i=0;i<100;i++)
{
int error= pthread_kill(threadList[i],SIGUSR1);
if(error) {perror("Failed signal"); errno=0;}
}
fprintf(stdout,"Final value of Counter? %lu\n",counter);
break;
case 'q': exit(0);
}
}
return 0;
}
【问题讨论】:
-
你可以用这个
echo new_size > /proc/sys/kernel/threads-max增加数量 -
您需要在
strace(或调试器)下运行程序以查看为什么线程创建失败。使用配置的线程大小,限制非常低。 -
“同时还展示了系统处理比进程多得多的 pthread 的能力。”。这并不完全正确。 linux 线程 [和大多数现代系统上的 pthreads] 是进程的同义词(即存在一对一映射,而不是一对多映射)。为防止拒绝服务,您的服务器设置了 75 个上限。有关更多信息,请参阅我的回答:stackoverflow.com/questions/39185134/…
-
threads-max 当前设置为 970007,所以这不是问题。
-
我可以在 VMWare 和其他版本的 Linus 下运行数千个进程,这表明进程和线程不是同义词。 strace 可能是一个很好的线索。在 Redhat 5.11 下,pthread_create 生成对克隆的调用。我需要将此与其他系统上的行为进行比较。
标签: c linux multithreading pthreads redhat