Linuxワークキューは、プロセスコンテキストを持つカーネルレベルのスレッドであることが意図されています。特定のプロセスコンテキストを持たないkthreadの代わりに使用しようとしていました。しかし、どうすればデータをワークキューに渡すことができますか? work_structには、atomic_long_t型のデータフィールドがあります。このフィールドへのポインタを渡すことができませんでした。どうすればいいのですか?
また、ワークキューの具体的な例は1つも見つかりませんでした。提案してもらえますか?
データをワークキュー関数に渡したい場合は、work_struct
構造を独自のデータ構造内に埋め込み、container_of
を使用してデータを取得します。
簡単な例として、カーネルはそれでいっぱいです-ちょうどgit grep work_struct
。簡単な例については、drivers/cpufreq/cpufreq.c
(handle_update
関数)を参照してください。以下の記事も最後に例を埋め込んでいますが、container_of
を使用せず、代わりに構造体の最初のメンバーがその親と同じアドレスを持っているという事実に依存しています。
http://www.ibm.com/developerworks/linux/library/l-tasklets/index.html
解決したようですが、ワークキューの使い方を理解するのにとても助かりました。 githubで簡単な例のコードをいくつか紹介します。これが、だれにとっても役立つことを願っています。
https://github.com/m0r3n/kernel_modules/blob/master/workQueue.c
次のMakefileを使用してコンパイルできます。
KVERSION = $(Shell uname -r)
obj-m = workQueue.o
all:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean
次の方法でモジュールを挿入します。
# sync; insmod workQueue.ko; sync
そして、ログを参照してください。
# tailf /var/log/kern.log
編集:私はちょうど遅れたバージョンを追加しました:
https://github.com/m0r3n/kernel_modules/blob/master/workQueueDelayed.c
デフォルトでは、作業関数は、パラメータとして打たれた作業で呼び出されます。スレッド内では、構造体のデータ要素を簡単に取得できます。また、Gnurouは、より多くのデータにアクセスするために、作業構造体を実装固有の構造内に配置し、スレッド内のマクロのコンテナーを使用してすべてのデータにアクセスできます。
ワークキューに関する簡単な説明
worqueueは、割り込み処理の下半分のメカニズムであり、作業の一部がカーネルスレッドに渡され、後で割り込みを有効にして実行します。 percpuスレッドevents/nはカーネルによって作成され、スレッドはドライバーコードによっても作成できます。構造はスレッドを識別するために使用され、構造内の重要なパラメーターは名前フィールドです。また、percpu構造も含まれています。スレッドが待機する待機キューヘッドと、作業を定義する構造、つまり関数とデータを追加するためのリンクリストが含まれます。ワーカースレッドはその構造を入力パラメーターとして取得します。スレッドは実行され、待機キューで誰かが待機します。スレッドをウェイクアップします。関数を定義する作業構造が作成されます。ワークキューがスケジュールされると、構造がリンクリストの末尾に追加され、ワーカースレッドがウェイクアップされます。ウェイクアップすると、ワーカースレッドはCPUごとの構造で定義されたリンクリストを実行し、作業構造をパラメーターとして定義された関数の実行を開始します。実行後、リンクリストからエントリを削除します。