我正在编写一个赋值程序,它使用线程在两个给定数组之间实现矩阵乘法。
我必须给出我想用作命令行参数的线程数,如果它们的数量小于第一个数组的行数,则重复使用相同的线程,直到整个作业完成。< / p>
我已经设法让它工作但只为数组的每一行使用一个线程。 例如,如果a具有5x5乘法并且使用少于5个线程,则会产生分段错误,这是有道理的。
我的问题是:如何在此线程完成其工作后重用一个线程? 在前面的例子中,我的意思是,如果我想使用2个线程作为5x5,我的程序应该像这样工作:
主题1-&gt;第1行
主题2-&gt;第2行
主题2-&gt;第3行
主题1-&gt;第4行
等
答案 0 :(得分:3)
你有几种可能性,但主要的想法是你必须监控线程以检测他们何时完成工作,并且有办法知道是否还有一些事情要做。
首先想到的是拥有一个专用线程来跟踪所有正在运行的线程,并在完成后回收它们。但是为了做到这一点,你需要一种让线程同步的机制,这可以使用信号量或互斥或消息来实现,但如果你不需要它就可能只是为了那个目的而编码很麻烦。
第二种方式只是要求他们回收自己,因为他们知道什么时候完成。在许多其他语言中,有一种称为continuation的机制,它可以让你完全相同,但由于我们正在处理C,我们需要手动完成。幸运的是,这里的延续实际上只是一项任务。
所以调用continuation的机制实际上只是一个函数,它首先运行由线程执行的任务,然后是:
显然,第一个选项会更简单,在你的情况下,你已经知道在设置时需要做什么,所以你的设置功能可以填充任务列表,然后根据需要启动任意数量的线程,让他们自己做回收。
这是一个你可以开始的简单骨架:
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
。