2017-05-19 15 views
-1

私はCでスレッドプールを作成しようとしています。そのため、各スレッドを引数として持つ結合関数を実装する必要があります。本質的にはthread_join関数に似ています。誰も私に簡単なスレッド結合関数を実装する方法に関するリソースを提供できますか?スレッドプール結合関数

//structure that contains a pthread 
struct ThreadID; 

// from this run method I am creating threads in a thread pool 
int ThreadPool_run(struct ThreadPool *, struct ThreadID *, void *(*run)(void *), void *); 

// this is the join function 
int ThreadPool_join(struct ThreadID, void **); 
+0

ようこそスタックオーバーフロー。 すぐに[About]と[Ask]ページをお読みください。あなたが作業しているプラ​​ットフォームと、これの下で使用する予定のスレッドライブラリについては、より具体的にする必要があることに注意してください。 Unix(POSIX pthreads)とWindowsではスレッド間に大きな違いがあり、C11規格には名目上スレッドサポートがありますが、必ずしも実装されているわけではありません。また、本、ツール、ソフトウェアライブラリ、チュートリアル、その他のオフサイトリソースを推薦するかどうかを尋ねる_questionsは、批判的な回答と迷惑メールを引き付ける傾向があるため、Stack Overflowの話題にはなりません._ –

+0

スレッドプールに参加することはほとんどありませんどんな意味でも。 javaの 'ExecutorService'とC#' ThreadPool'がどのように機能するかを調べたいかもしれません。彼らはあなたが参加できる未来またはタスクオブジェクトを返します。スレッドプール内のスレッドに参加することは決してありません。実行を停止することは決してありません(他のタスクを実行中)。 – sturcotte06

答えて

2

スレッドプールの概念を完全に理解しているかどうかはわかりません。あなたは、スレッドプールインターフェースに入るスレッドの概念を持つべきではありません。実際、私はjavaのExecutorServiceの名前を好む。それは概念をよりよくカプセル化します。基本的には、スレッドの寿命を気にすることなく、タスクを非同期に実行したいとします。

typedef struct executor executor_t; 
typedef struct executor_options executor_options_t; 
typedef struct executor_task executor_task_t; 
typedef struct blocking_queue blocking_queue_t; 
typedef struct future future_t; 
typedef void *(*task_t)(void* data); 

int executor_init(const executor_options_t options); 
int executor_submit(const executor_t *const executor, future_t *const future, const task_t task, const void *const data); 
int executor_destroy(const executor_t *const executor); 

int blocking_queue_init(blocking_queue_t *const queue); 
int blocking_queue_enqueue(const blocking_queue_t *const queue, const void *const data); 
int blocking_queue_dequeue(const blocking_queue_t *const queue, const void ** data); 
int blocking_queue_destroy(const blocking_queue_t *const queue); 

int future_init(future_t *const future); 
int future_wait(const future_t *const future); 
int future_destroy(const future_t *const future); 

構造は次のようになります:

struct executor_options { 
    int min_thread; 
    int max_thread; 
    int max_idle_ms; 
}; 

struct executor { 
    pthread_mutex_t mutex; 
    pthread_t *threads; 
    executor_options_t options; 
    blocking_queue_t *queue; 
}; 

struct executor_task { 
    task_t task; 
    void *data; 
    future_t *future; 
}; 

struct blocking_queue { 
    executor_task_t *tasks; 
    pthread_mutex_t mutex; 
    pthread_cond_t empty; 
    pthread_cond_t full; 
    bool_t is_empty; 
    bool_t is_full; 
}; 

struct future { 
    void *result; 
    pthread_mutex_t mutex; 
    pthread_cond_t computed; 
    bool_t is_computed; 
}; 

executor_initでは、あなたがすべてのスレッドを初期化します

このようなサービスは、次のようになりますインターフェイスを持っているでしょう。これらのスレッドは、タスクを待っているキューでブロックし、実行し、将来の状態を通知して待機中のブロックを解除する必要があります。 executor_submitでは、与えられた未来を初期化し、未来と共にタスクを非同期的に計算するようにキューに入れる必要があります。将来は、ユーザがタスクの結果を待つために使用可能でなければなりません。最後に、executor_destroyは、残りのすべてのタスクが計算されるのを待つ必要があり、新しいタスクがサブミットされるのを防ぎます。最終的にすべてのリソースを解放してリターンします。