【问题标题】:pthreads : allowed number of threadspthreads : 允许的线程数
【发布时间】:2011-03-24 04:46:34
【问题描述】:

我已经在一个使用 pthreads 的小型 C 程序上工作了几天。昨天我或多或少都在寻找死锁错误,但现在我发现问题并不是真正的死锁错误。下面这段代码有完全相同的问题。

#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;
}

对于 NTHREADS

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

并按其应有的方式终止。但是,如果我使用 NTHREADS >= 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 = 382(而不是 506)。

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

谁能向我解释我做错了什么以及这段代码的根本问题是什么?我想这一定是对允许线程数的某种限制,但是我应该如何处理呢?

【问题讨论】:

  • 保证您能够运行 64 个线程(具有默认属性)。除此之外,这是实施的礼物。

标签: c pthreads


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    除了 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);
        }
    

    【讨论】:

      猜你喜欢
      • 2012-10-12
      • 1970-01-01
      • 2022-01-16
      • 2011-03-17
      • 1970-01-01
      • 1970-01-01
      • 2012-04-27
      • 2016-05-21
      • 2019-04-04
      相关资源
      最近更新 更多