はじめに
前回はカーネルモジュールで出力をやるところまでやった。
rabbitfoot141.hatenablog.com
今回は、気合でカーネルスレッドを扱えるようにする。
実装
EchoサーバではTCPを使用する、それをスレッドでああだこうだして複数接続を可能にしたい。
その目的のために今回は頑張ってカーネルスレッドを実装する。
kernel moduleでカーネルスレッド
参考にしたのはまつもとりーさんの次の記事。
hb.matsumoto-r.jp
linux/kthread.hとlinux/sched.hいうヘッダーファイルにある関数を使う。
kthread.hがカーネルスレッドに関するあれこれで、sched.hがカーネルで扱うプロセスやそれを扱うtask_structという構造体を使うためにある。
それでは早速コードを晒す。
#include <linux/kthread.h> #include <linux/sched.h> struct task_struct *task; static int kthread_cb(void *arg){ printk("[%s] running as kthread\n", task->comm); while(!kthread_should_stop()){ schedule(); } return 0; }
グローバル変数としてtask_structを宣言している。
これにプロセスとして起動したいあれこれを代入して使う。
kthread_cb関数ではカーネルスレッドとしての動かしたい処理を書いている。
それを次のモジュール本体のコードで次のように使う。
static int fastecho_init_module(void){ printk("Fastest Echo Server Start!!"); //make kernel thread task = kthread_create(kthread_cb, NULL, "lrf141:fastecho"); printk("[%s] wake up as kthread\n", task->comm); //launch task wake_up_process(task); return 0; } static void fastecho_cleanup_module(void){ printk("Fastest Echo Server is unloaded!"); printk("[%s] stop kthread\n", task->comm); kthread_stop(task); }
まず前のコードで宣言したtask_structにkthread_create関数の戻り値を代入する
これでスレッドが使える様になるので、printkの次でwake_up_process関数を呼び出し、プロセスとして起動する
rmmod時にはそれを止める処理を書いている。
これを前回のモジュール本体に組み込んで次のようにする。
$ make $ sudo insmod fastecho.ko $ ps auwx | grep "\[lrf141:faste cho\]" root 30557 98.3 0.0 0 0 ? R 16:49 0:05 [lrf141:fast echo] $ dmesg [176532.823327] Fastest Echo Server Start!! [176532.826178] [lrf141:fastecho] wake up as kthread [176532.827453] [lrf141:fastecho] running as kthread [176586.304842] Fastest Echo Server is unloaded![lrf141:fastecho] stop kthrea d $ sudo rmmod fastecho.ko
おわりに
まつもとりーさんの記事のおかげでなんとかカーネルスレッドを動かすことはできたので
次はネットワークの部分を実装していきたい。