2012-11-14 49 views
2

我正在写一个赋值的程序,它使用线程在两个给定数组之间实现矩阵乘法。重用相同的线程

我必须给出我想用作命令行参数的线程数量,如果它们的数量小于第一个数组的行数,则重复使用一些相同的线程,直到完成整个工作。

我已经设法使它工作,但只对数组的每一行使用一个线程。 例如,如果有一个5​​x5乘法,并使用少于5个线程我采取了分段错误,这是有道理的。

我的问题是:如何在线程完成工作后重用线程? 在前面的例子,我的意思是,如果我想使用2个线程对5x5的我的程序应该像这样工作:

线程1-> 1个线

线程2-> 2号线

线2->线3

螺纹1-> 4行

+0

请发表一些代码 – CCoder

回答

3

您有几种可能性,但主要的思想是你必须监控线程以检测他们完成工作的时间,并且有办法知道是否还有其他事情要做。

想到的第一种方法是有一个专用线程来跟踪所有正在运行的线程,并在完成后回收它们。但是为了做到这一点,您需要一种让线程同步的机制,可以使用信号量或互斥体或消息来实现线程,但是如果您已经不需要它,那么为此编写代码可能会很麻烦。

第二种方法只是要求他们回收自己,因为他们知道什么时候完成。在许多其他语言中,有一种称为continuations的机制,它可以完全实现这一点,但由于我们正在处理C,因此我们需要手动完成。幸运的是,这里的延续实际上只是一项任务。

所以调用延续的机制实际上仅仅是一个函数,它会先运行由线程执行的任务,然后:

  • 检查任务列表。该任务列表必须在安装时填写需要由任务完成的所有工作,
  • 将线程添加到可用线程的队列中,该线程必须由其他线程再次检查并重新分配新任务,

显然,第一种选择会更容易,而在你的情况,你已经知道在安装时有什么必须做,所以你的设置功能,可以填补的任务列表,然后启动尽可能多的线程数你想要的,并让他们自己做回收。

这里有一个简单的框架,你可以下手:

typedef struct { 
    /* task related data */ 
} task_t; 

// basic list structure 
typedef struct { 
    list_t *next; 
    void *data; // here app specific data 
} list_t; 

list_t task_list; // your task list 

// a few operators to manipulate a list 
// implementation must use a mutex to avoid race conditions 
void list_push(list *l, void *data); 
void *list_pop(list *l); 


// thread function 

void do_task(task_t *task){ 
    while (task) { 
     run_task(task); // that would be the matrix related function 
     task = list_pop(&task_list); 
} 

// here a simple define for the number of threads 
// you might want to check the number of available cores instead 

#define MAX_THREAD_COUNT 4 

int main() { 

    pthread_t threads[MAX_THREAD_COUNT]; 

    setup_task_list(); // push all the work that must be done in the list 
    int i; 
    for (i = 0; i < MAX_THREAD_COUNT; i++) { 
     pthread_create(threads + i, NULL, do_task, list_pop(&task_list)); 
    } 

    // here wait for all the threads, or detach them 

} 

这是你可以做一个基本的轮廓,应该让你开始。 关于SO处理C链接列表有几个问题。这里的一个必须是同步的,不应该阻塞,并且在空时返回NULL

+0

感谢您的回答。我理解了2种方式。第二种对我来说似乎更容易,但我会尝试使用互斥体作为分配说。感谢您的回复。 – SpyrosR

+2

在第二个设置中,无论如何,您将不得不为链接列表使用互斥锁。 – didierc

+0

好吧,通过使用一个简单的互斥体为每个时刻计算的行修复它。我的程序工作正常,打印最终结果如预期使用任何数量的线程。但我有最后一个问题。我使用打印语句来检查哪个线程在当前行上运行。这在5x5矩阵示例中显示,只有线程1在所有行上运行,并且只有在一些随机运行后,我才能看到一行中线程2在此操作。是否合乎逻辑?我假设它发生的原因是在一个小矩阵中,所有的操作都非常快,并且没有为线程2留下任何工作。是对的吗? – SpyrosR

相关问题