いくつかの可能性がありますが、主な考え方は、スレッドを監視して、ジョブがいつ終了したかを検出し、まだやるべきことが残っているかどうかを知る方法を用意する必要があるということです。
頭に浮かぶ最初の方法は、実行中のすべてのスレッドを追跡する専用のスレッドを用意し、終了したらそれらをリサイクルすることです。ただし、そのためには、スレッドを同期させるメカニズムが必要です。これは、セマフォやミューテックス、またはメッセージを使用して実装できますが、その必要がない場合、その目的のためだけにコーディングするのは面倒です。 .
2 番目の方法は、自分でリサイクルするよう依頼することです。他の多くの言語には、継続と呼ばれるメカニズムがあり、まさにそれが可能ですが、C を扱っているため、手動で行う必要があります。幸いなことに、ここでは継続は実際には 1 つのタスクにすぎません。
したがって、継続を呼び出すメカニズムは実際には単なる関数であり、スレッドによって実行されるタスクを最初に実行し、次に次のいずれかを実行します。
- タスクリストを確認します。このタスク リストには、セットアップ時に、タスクで実行する必要があるすべての作業を入力する必要があります。
- 使用可能なスレッドのキューにスレッドを追加します。これは、他のスレッドによって再度チェックされ、新しいタスクが再割り当てされる必要があります。
明らかに、最初のオプションの方が簡単です。あなたの場合、セットアップ時に何をしなければならないかをすでに知っているので、セットアップ関数はタスクのリストを埋めてから、必要な数のスレッドを起動して、それらを許可することができますリサイクルは自分たちで。
以下は、最初に使用できる簡単なスケルトンです。
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
}
これは、できることの基本的な概要であり、開始する必要があります。C リンク リストを扱う SO についていくつか質問があります。ここにあるものは同期する必要があり、ブロックしてはならず、NULL
空になると戻ります。