pthreads:允许的线程数

时间:2010-08-02 12:30:05

标签: c pthreads

我现在已经在使用pthreads的小型C程序上工作了几天。我昨天花了或多或少花了所有寻找死锁的bug,但现在我发现这个问题并不是真正的僵局。以下代码具有完全相同的问题。

#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
#define NTHREADS 507

pthread_mutex_t runningThreadsMutex;
pthread_cond_t runningThreadsCond;
int runningThreads = 0;

void* HelloWorld(void* arg) {
  sleep(1);

  pthread_mutex_lock(&runningThreadsMutex);
  runningThreads--;
  printf("End thread %d\n", runningThreads);
  pthread_cond_signal(&runningThreadsCond);
  pthread_mutex_unlock(&runningThreadsMutex);

  return NULL;
}

int main() {
  pthread_t thread;

  pthread_mutex_init(&runningThreadsMutex, NULL);
  pthread_cond_init(&runningThreadsCond, NULL);

  for (int i = 0; i < NTHREADS; ++i) {
    pthread_mutex_lock(&runningThreadsMutex);
    printf("Create thread %d\n", runningThreads++);
    pthread_mutex_unlock(&runningThreadsMutex);
    pthread_create(&thread, NULL, HelloWorld, NULL);
  //  pthread_detach(thread);
  }

  pthread_mutex_lock(&runningThreadsMutex);
  while(runningThreads > 0) {
    pthread_cond_wait(&runningThreadsCond, &runningThreadsMutex);
  }
  pthread_mutex_unlock(&runningThreadsMutex);
  return 0;
}

上面的代码似乎在我的笔记本电脑(64位Linux机器)上很好地用于NTHREADS&lt;在这种情况下,它会打印出类似这样的内容:

Create thread 0
Create thread 1
.
.
.
Create thread 505
End thread 505
End thread 504
.
.
.
End thread 0

并且应该终止。但是,如果我使用NTHREADS&gt; = 506,例如NTHREADS = 510我得到

Create thread 0
Create thread 1
.
.
.
Create thread 509
End thread 509
End thread 508
.
.
.
End thread 4

它停止而没有终止。所以似乎最后四个(510-506 = 4)线程永远不会终止(或者根本不会启动?)。

我在旧的32位linux机器上也试过这个代码。在那里我得到了相同的行为,除了它适用于NTHREADS&lt; 382但不适用于NTHREADS&gt; = 382(而不是506)。

当我搜索解决方案时,我也发现了这个问题:http://bytes.com/topic/c/answers/728087-pthreads-limit,在使用pthread_join时有人遇到同样的问题(使用pthreads时可能会更自然)但是它们没有任何好处解释

任何人都可以向我解释我做错了什么以及这段代码的根本问题是什么?我想这必须对允许的线程数量有某种限制,但我应该如何处理呢?

2 个答案:

答案 0 :(得分:5)

您需要检查pthread_create的返回值。如果它不为零,则函数无法创建线程。一个典型的问题是新线程的堆栈内存不足。例如每个线程使用1Mb堆栈,系统将需要至少510Mb的可用内存来启动510个线程。

你为什么要运行这么多线程?除非你有一个包含数百个处理器的大规模并行系统,否则这些线程将争夺CPU时间和其他资源。您可能会以更少的线程(与系统中处理器数量相同的数量级)以最合适的顺序完成工作。

答案 1 :(得分:4)

添加到Anthony的答案,您可以使用以下代码重置线程的堆栈分配:

pthread_attr_t threadAttr;
size_t threadStackSize = 65536;   // this is the stack size in bytes, 
                                  // must be over 16384 for Linux 
pthread_attr_init(threadAttr);
pthread_attr_setstacksize(&threadAttr,threadStackSize);

    if( pthread_create(&threadId,&threadAttr,funcn,NULL) != 0 )
    {
        printf("Couldn't create thread\n");
        exit(1);
    }