1

カーネル 3.x のスレッディングに関する Linux カーネル プログラミングの優れたチュートリアルや例はどこにありますか?

任意の助けをいただければ幸いです.....

4

1 に答える 1

1

カーネルで作業を延期するいくつかの方法を掘り下げることをお勧めします(それが最終的に必要になるからです)。

あなたが明示的に求めたものに最も近い解決策は、使用することです

struct task_struct * kthread_create(int (*threadfn) (void *data), void * data, const char namefmt[], ...);

問題に適合する可能性のある別の方法は、ワーク キューの使用です。これにより、最初に延期したい作業を宣言する必要があります。作業構造を割り当てたい場所に応じて、2 つのプリプロセッサ マクロを使用してこれを行うことができます。

  • スタック上:は、実行時に供給されるワーカー関数を使用して、スタック上のDECLARE_WORK(name, void (*func)(void*), void *data);a を自動的に初期化します。struct work_structfuncdata
  • ヒープ上: 既にstruct work_structオブジェクトを割り当てており、関数と適切なデータで初期化したいだけだとします。次に、使用する必要がありますINIT_WORK(struct work_struct *work, void (*func)(void*), void *data);

タスクを実行したい場合は、スケジュールする必要があります。その後、関連する作業キューのワーカー スレッドで実行する作業のリストに表示されます。デフォルトのワーク キューを使用するだけの場合は、次の 2 つの関数のいずれかを使用する必要があります。

int schedule_work(struct work_struct *work);
int schedule_delayed_work(struct work_struct *work, unsigned long delay);

delayjiffy (プロセッサ クロックの目盛り)で表されます。

カスタム ワーク キューを作成した場合は、他の関数を使用する必要があります。しかし、最初に、独自のワーク キュー オブジェクトを作成する方法を見てみましょう。これを実現するには、次のように呼び出すだけです。

struct workqueue_struct create_workqueue(const char *name);

完了したら、前に表示された 2 つの機能と同様の機能を使用して、保留中の作業をキューに追加できます。

int queue_work(struct workqueue_struct *wq, struct work_struct *work);
int queue_delayed_work(struct workqueue_struct *wq,
    struct work_struct *work, unsigned long delay);

保留中の作品リストをフラッシュしたい場合は、次のようにします:

/* On the default work queue */
void flush_scheduled_work(void);

/* On a dynamically created work queue */
void flush_workqueue(struct workqueue_struct *wq);

これは、まだ準備が整っていない遅延作業をフラッシュすることに注意してください... 遅延作業をキャンセルしたい場合は、 を使用する必要がありますint cancel_delayed_work(struct work_struct *work);ワーカー スレッドは次のように動作します。

  1. 実行する作業のリストが空でない場合:
    1. リスト(struct work_structオブジェクト)の先頭にある作業を取得します。
    2. 作業構造体が格納されている場合は、オブジェクトfuncが渡されたオブジェクトを実行します。datastruct work_struct *work(*work->func)(work->data);
  2. スケジュールされた作業リストが空の場合、スリープ状態になります。その後、作業を​​スケジュールすると、目が覚めます。

明らかに、この 2 番目のオプションは、バックグラウンド タスクを常に実行できる状態にしておく必要がある場合には適していません。この場合、標準kthreadが必要です。リンクしたマニュアルページを参照してください。使用方法が非常に明確に説明されています。

問題に答えるために、2 つのスレッドを実行できます。送信者と受信者。受信側には受信パケットが供給されます (これは見た目よりも複雑になる可能性があり、irq handlersそのために対処する必要がある場合があります ...)。したがって、このkthread_createオプションはあなたにとって良いものです。一方、送信するデータを取得したとき (送信者の場合)、または適切なパケットを受信したとき (受信者) に、下半分をスケジュールして 1 回実行することができます。この場合、作業キュータスクレット(またはsoftirqs ) を使用する必要がある場合があります。現在時間がなくなっているので、後で投稿を編集してこれらの獣について説明します.

于 2013-10-18T07:03:57.817 に答える