2010-08-02 67 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); 
    }