您有几种可能性,但主要的思想是你必须监控线程以检测他们完成工作的时间,并且有办法知道是否还有其他事情要做。
想到的第一种方法是有一个专用线程来跟踪所有正在运行的线程,并在完成后回收它们。但是为了做到这一点,您需要一种让线程同步的机制,可以使用信号量或互斥体或消息来实现线程,但是如果您已经不需要它,那么为此编写代码可能会很麻烦。
第二种方法只是要求他们回收自己,因为他们知道什么时候完成。在许多其他语言中,有一种称为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
。
请发表一些代码 – CCoder