2009-12-03 38 views
0

我在课堂上要求我们使用POSIX线程和创建N *转让(N-1),其中/ 2来处理的数据集的n个元素。Ç - POSIX线程的海量#失控,不再创造新的

你可以把它看作基本概率经典的“握手”。

我知道,对于一个大的数据集,这将使得应用程序CPU绑定,并最终将花费这么多时间的上下文切换,这将是无用的,但任务要求我们做到这一点。

但是,我循环创建的所有线程停止一段时间后,他们创造。

对于下面的代码,我会看到输出如下:

making thread 
thread start 
thread done 
made thread 1944 
making thread 
thread start 
thread done 
made thread 1945 
making thread 
thread start 
thread done 
made thread 1946 
making thread 

了一段时间,但我不会再看到“线程启动”和“线程中完成”的消息,只看到了“制作线程,发线程“消息。

下面是创建线程的循环:

int tCtr = 0; 
    tArr = (pthread_t*)malloc(((numbers_read) * (numbers_read - 1)/2) * sizeof(pthread_t)); 
    for(i=0; i<numbers_read; i++){ 
     int j; 
     for(j=i; j<numbers_read; j++){ 
      // n(n-1)/2 
      if(i != j){ 
       printf("making thread\n"); 
       struct comparison_struct *data; 
       data = (struct comparison_struct *)malloc(sizeof(struct comparison_struct)); 
       data->i_value = &numbers[i]; 
       data->j_value = &numbers[j]; 
       data->i_arr_entry = &wArr[i]; 
       data->j_arr_entry = &wArr[j]; 
       pthread_create(&tArr[tCtr], NULL, compare_thread, (void *)data); 
       printf("made thread %d\n", tCtr); 
       tCtr++; 
      } 
     } 
    } 
    for(i=0; i<tCtr; i++){ 
     pthread_join(tArr[i], NULL); 
    } 
    free(tArr); 

这里是包含线程代码子程序:

void *compare_thread(void *vData) { 
    printf("thread start\n"); 
    struct comparison_struct *data; 
    data = (struct comparison_struct *)vData; 
    if(*data->i_value <= *data->j_value){ 
     *data->i_arr_entry = 0; 
    } else { 
     *data->j_arr_entry = 0; 
    } 
    free(vData); 
    printf("thread done\n"); 
    return NULL; 
} 

任何人有什么想法?我对pthreads很陌生,无法搞清楚。

我知道如果我在pthread_create之后立即调用pthread_join,应用程序就可以工作 - 但它会阻塞每个线程,我认为这会降低性能,因为实际上只有2个线程运行在时间。

+0

我不会太担心的表现,除非它的任务的一部分或程序需要永远运行。性能的限制因素是创建和销毁线程的数量。不管你有多少能够平行的线程,大部分的工作都是在你的主线程中完成的。这不是一个非常实际的优化方案,因为在几乎所有的情况下,这都是你的瓶颈,你会减少线程数量,并为每一个线程做更多的工作。随着登录,真正的瓶颈可能是终端,其他一切都可以忽略不计。 – 2009-12-03 03:47:21

回答

4

检查在pthread_create的返回值,也许你打的资源限制。

pthread_create() will fail if: 

[EAGAIN]   The system lacked the necessary resources to create 
        another thread, or the system-imposed limit on the 
        total number of threads in a process 
        [PTHREAD_THREADS_MAX] would be exceeded. 

[EINVAL]   The value specified by attr is invalid. 

如果要达到资源限制,你可以尝试让这对其他线程加入一个线程,使工人的队列,并通过队列给工作,每个线程,或者如果你控制系统的资源限制尝试增加它。

+1

或者对于Mickey Mouse修复Mickey Mouse问题,稍微展开一下这个循环,以便创建几个线程,然后加入所有这些线程,然后创建更多等等。该任务可能会说你必须创建所有这些线程,但它是否表示你必须让它们全部运行? ;-) – 2009-12-03 03:28:01

0

如果我在pthread_create之后立即调用pthread_join ...那么它会阻塞每个线程......实际上一次只能运行2个线程。

加入线程的替代方法是将它们创建为分离的。创建并初始化一个pthread_attr_t,将其设置为已分离,并将您的调用传递给attr。

pthread_attr_t attr; 
int    ret; 

ret = pthread_attr_init(&attr); 
if (ret) 
    // error ......... 

ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 

for (....) 
{ 
    //........ 
    ret = pthread_create(&tArr[tCtr], &attr, compare_thread, (void *)data); 
    //....... 
} 

ret = pthread_attr_destroy(&attr); 

也没有要求创建另一个线程的线程必须是加入它的线程。您可以创建一个线程来加入所有其他创建的线程。但这可能超出了这项任务的责任。