ワークキュー

2907 ワード

カーネルバージョン:Linux-2.6.32.2
ワークキューはtaskletと同様で、カーネルコードが将来実行される(すぐに実行されない)関数を要求することを可能にします.ワークキュー関連APIはで.ワークキューを使用するには、2つの方法があります.1つは、自分でワークキューを作成することです.2つ目は、カーネルが提供するワークキュー(共有方式)を使用することです.
一、まず自分がワークキューを作成する方法を見てみましょう.
ワークキュー使用構造体struct workqueue_structは、ワークキューを作成するには2つのAPI、すなわちcreate_があることを説明する.workqueueとcreate_singlethread_workqueue、プロトタイプは次のとおりです.
struct workqueue_struct *create_workqueue(const char *name);
struct workqueue_struct *create_singlethread_workqueue(const char *name);
例:
struct workqueue_struct *keventd_wq;
keventd_wq = create_workqueue("events");
create_workqueue関数は、システム内の各プロセッサにスレッド(マルチスレッド)を作成し、create_singlethread_workqueueは単一のスレッドを作成するだけで、単一のスレッドが十分に使用できる場合はcreate_を使用します.singlethread_workqueue関数.
ワークキューにタスクをコミットするには、まずstruct work_を入力する必要があります.struct、遅延タスクstruct delayed_を使用work、カーネルは関連マクロを提供します.
DECLARE_WORK(name, void (*func)(void *));
INIT_WORK(struct work_struct *work, void (*func)(void *));
DECLARE_WORKマクロは、ワークを静的に定義するために使用されます.struct.INIT_WORKマクロはワークを動的に初期化するために使用されます.struct.
遅延タスクINIT_の使用DELAYED_WORKマクロを初期化します.
INIT_DELAYED_WORK(struct delayed_work, void (*func)(void *));

タスクをワークキューにコミットするには、カーネルには次の2つのAPIがあります.
int queue_work(struct workqueue_struct *wq, struct work_struct *work);
int queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *work, unsigned long delay);
の2つの関数は、queue_を使用してタスクをワークキューにコミットします.delayed_work関数では、コミットされたタスクは、パラメータdelayによって指定された時間だけ実行されます.
ワークキュー内のタスクをキャンセルする場合はcancel_を使用します.delayed_work、プロトタイプは以下の通りです.
int cancel_delayed_work(struct work_struct *work);
タスクが実行される前にキャンセルされた場合、cancel_delayed_work関数はゼロ以外の値を返します.この関数を呼び出すと、カーネルはキャンセルされたタスクが実行されないことを確認します.ただし0を返すと、タスクが実行されたためcancel_が呼び出されます.delayed_work関数の後もタスクが実行されている可能性があるので、タスクの測地がキャンセルされることを確認するためにflush_を呼び出す必要があります.workqueue関数.
void flush_workqueue(struct workqueue_struct *wq);

ワークキューの使用が完了したらdestroy_を使用できます.workqueueワークキューの破棄:
void destroy_workqueue(struct workqueue_struct *wq);

二、カーネルを使用する共有ワークキュー
カーネルは初期化時にワークキュー「events」を作成します.このワークキューは共有されているので、このキューに簡単なタスク処理をコミットできます.このワークキューはすでに作成されているので、作成する必要はありません.直接ワークキューにタスクをコミットすればいいです.カーネルはAPIを提供しています.
int schedule_work(struct work_struct *work);
int schedule_delayed_work(struct delayed_work *work, unsigned long delay);
ですが、この2つの関数は最終的に呼び出された前のカーネルが提供する関数です.ワークキューはカーネル内のkeventd_です.wq.
共有ワークキューにコミットされたタスクをキャンセルする場合は、前のcancel_も使用できます.delayed_work関数、cancel_の場合delayed_work関数は0を返し、前のflushを使用しません.workqueue関数ではなくflush_を使用します.scheduled_work関数.
void flush_scheduled_work(void);