kthread_create_on_node関数
kthread_create_on_node関数の機能:指定されたメモリノードに新しいカーネルスレッドを作成します。ソースコードは以下の通りです。
実践例
#include <linux/module.h>
#include <linux/pid.h>
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/wait.h>
int KernelWorkerFunction(void* data) {
printk("ワーカースレッドが開始されました\n");
printk("ワーカースレッドのPID: %d\n", current->pid);
printk("ワーカースレッドが終了します\n");
return 0;
}
static int __init KthreadCreationInit(void) {
struct task_struct* new_thread = NULL;
printk("kthread_create_on_nodeの初期化開始\n");
// メモリノード-1(デフォルトノード)に新しいスレッドを作成
new_thread = kthread_create_on_node(KernelWorkerFunction, NULL, -1, "kernel_worker");
if (IS_ERR(new_thread)) {
printk("スレッド作成に失敗\n");
return PTR_ERR(new_thread);
}
printk("新規スレッドのPID: %d\n", new_thread->pid);
// スレッドを起動
wake_up_process(new_thread);
printk("メインスレッドのPID: %d\n", current->pid);
return 0;
}
static void __exit KthreadCreationExit(void) {
printk("カーネルモジュール終了: KthreadCreationExit\n");
}
MODULE_LICENSE("GPL");
module_init(KthreadCreationInit);
module_exit(KthreadCreationExit);
wake_up_process関数
wake_up_process関数の機能:スリープ状態のプロセスを起床させ、その状態をRUNNINGに変更して、CPUによる再スケジューリングを促します。
- 起床に成功した場合は1を返す
- 起床に失敗した場合(スレッドがすでにRUNNING状態の場合)は0を返す
ソースコードは以下の通りです:
実践例
#include <linux/kthread.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/module.h>
#include <linux/pid.h>
#include <linux/list.h>
#include <linux/delay.h>
struct task_struct* target_thread = NULL;
int WorkerThreadFunction(void* data) {
int result = -1;
printk("ワーカースレッド関数開始\n");
printk("ワーカースレッドのPID: %d\n", current->pid);
// 親プロセスの状態を確認
printk("親プロセスの初期状態: %ld\n", target_thread->state);
// 親プロセスを起床
result = wake_up_process(target_thread);
printk("wake_up実行後の親プロセス状態: %ld\n", target_thread->state);
printk("wake_upの戻り値: %d\n", result);
printk("ワーカースレッド関数終了\n");
return 0;
}
static int __init ProcessWakeupInit(void) {
int wakeup_result = 1;
char thread_name[] = "process_watcher";
struct task_struct* created_thread = NULL;
long timeout_value;
wait_queue_head_t wait_queue;
wait_queue_entry_t wait_entry;
printk("プロセス起床テストの初期化開始\n");
// 指定されたノードに新しいカーネルスレッドを作成
created_thread = kthread_create_on_node(WorkerThreadFunction, NULL, -1, thread_name);
if (IS_ERR(created_thread)) {
printk("スレッド作成に失敗\n");
return PTR_ERR(created_thread);
}
printk("新規スレッドのPID: %d\n", created_thread->pid);
printk("現在のスレッドのPID: %d\n", current->pid);
// 待ち行列を初期化
init_waitqueue_head(&wait_queue);
init_waitqueue_entry(&wait_entry, current);
add_wait_queue(&wait_queue, &wait_entry);
target_thread = current;
// 作成したスレッドを起床
wakeup_result = wake_up_process(created_thread);
printk("新規スレッド起床結果: %d\n", wakeup_result);
// タイムアウトまでスケジューリング
timeout_value = schedule_timeout_uninterruptible(2000*10);
// 現在のスレッドを起床
wakeup_result = wake_up_process(current);
printk("現在のスレッド起床結果: %d\n", wakeup_result);
printk("schedule_timeout_uninterruptibleの戻り値: %ld\n", timeout_value);
printk("プロセス起床テストの初期化終了\n");
return 0;
}
static void __exit ProcessWakeupExit(void) {
printk("プロセス起床テストの終了処理\n");
}
module_init(ProcessWakeupInit);
module_exit(ProcessWakeupExit);