【问题标题】:pthreads: can't generate more than 70 under Redhat 6.8pthreads:在 Redhat 6.8 下不能生成超过 70 个
【发布时间】: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 下运行,我能够生成数千个线程,这是我所期望的。

问题发生时,会在 ma​​in 中的初始 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 &gt; /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


【解决方案1】:

是的,在 linux 下,线程和进程的处理方式非常相似。

如果您将进程限制设置为 75,这实际上是对用户所有进程的线程总数的限制。所以这是按设计工作的。

使用 ulimit 命令或在/etc/limits.conf 中设置进程数限制 它与 setrlimit() 系统调用一起应用, 来自其documentation

RLIMIT_NPROC 这是进程的最大数量(或者,更准确地说,在 Linux,线程)可以为真实用户 ID 创建 调用进程。

【讨论】:

  • ulimit 是 Bash/POSIX shell 内置命令,但如果使用非 Bash、非 POSIX shell,还有外部命令 prlimit
猜你喜欢
  • 2017-01-16
  • 1970-01-01
  • 1970-01-01
  • 2020-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-29
相关资源
最近更新 更多