【发布时间】:2010-12-22 16:21:38
【问题描述】:
我在课堂上有一个作业,要求我们使用 POSIX 线程并创建 n*(n-1)/2 个线程来处理包含 n 个元素的数据集。
您基本上可以将其视为概率中的经典“握手”。
我知道,对于大型数据集,它会使应用程序受 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 个线程.
【问题讨论】:
-
我不会太担心性能,除非它是任务的一部分或者程序需要永远运行。性能的限制因素是创建和销毁 squillions 线程。不管你可以并行化线程做什么,这里的大部分工作都是在你的主线程中完成的。这不是一个非常现实的优化方案,因为在几乎所有瓶颈的情况下,您都会减少线程数并给每个线程更多的工作。登录后,真正的瓶颈可能是终端,其他一切都可以忽略不计。