2010-08-02 64 views
1

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

#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 < 506很好地工作。在这种情况下,它打印出这样的事:

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,但不适用于NTHREADS> = 382(而不是506)。

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

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

+1

你保证运行64个线程(默认属性)的能力。除此之外,这是实施的礼物。 – 2011-08-30 23:20:31

回答

5

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

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

4

添加到安东尼的回答,您可以重新设置堆栈分配使用下面这段代码的线程:

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