C LANGUAGE TECHNOLOGY

【C言語】LinuxにおけるリアルタイムスケジューリングRMとEDFの実装

2022年4月27日

悩んでいる人
悩んでいる人

C言語でLinuxにおけるリアルタイムスケジューリングRMとEDFの実装を教えて!

こういった悩みにお答えします.

本記事の信頼性

  • リアルタイムシステムの研究歴12年.
  • 東大教員の時に,英語でOS(Linuxカーネル)の授業.
  • 2012年9月~2013年8月にアメリカのノースカロライナ大学チャペルヒル校(UNC)コンピュータサイエンス学部で客員研究員として勤務.C言語でリアルタイムLinuxの研究開発.
  • プログラミング歴15年以上,習得している言語: C/C++PythonSolidity/Vyper,Java,Ruby,Go,Rust,D,HTML/CSS/JS/PHP,MATLAB,Verse(UEFN), Assembler (x64,aarch64).
  • 東大教員の時に,C++言語で開発した「LLVMコンパイラの拡張」,C言語で開発した独自のリアルタイムOS「Mcube Kernel」GitHubにオープンソースとして公開
  • 2020年1月~現在はアメリカのノースカロライナ州チャペルヒルにあるGuarantee Happiness LLCのCTOとしてECサイト開発やWeb/SNSマーケティングの業務.2022年6月~現在はアメリカのノースカロライナ州チャペルヒルにあるJapanese Tar Heel, Inc.のCEO兼CTO.
  • 最近は自然言語処理AIイーサリアムに関する有益な情報発信や,Unreal Editor for Fortnite(UEFN)でゲーム開発に従事.
    • (AI全般を含む)自然言語処理AIの論文の日本語訳や,AIチャットボット(ChatGPT,Auto-GPT,Gemini(旧Bard)など)の記事を50本以上執筆.アメリカのサンフランシスコ(広義のシリコンバレー)の会社でChatGPT/Geminiを訓練するプロンプトエンジニア・マネージャー・Quality Assurance(QA)の業務委託の経験あり.
    • (スマートコントラクトのプログラミングを含む)イーサリアムや仮想通貨全般の記事を200本以上執筆.イギリスのロンドンの会社で仮想通貨の英語の記事を日本語に翻訳する業務委託の経験あり.
    • UEFNで10本以上のゲームを開発し,フォートナイト上で公開(FortniteFortnite.GG).

こういった私から学べます.

C言語を独学で習得することは難しいです.

私にC言語の無料相談をしたいあなたは,公式LINE「ChishiroのC言語」の友だち追加をお願い致します.

私のキャパシティもあり,一定数に達したら終了しますので,今すぐ追加しましょう!

友だち追加

独学が難しいあなたは,元東大教員がおすすめするC言語を学べるオンラインプログラミングスクール5社で自分に合うスクールを見つけましょう.後悔はさせません!

C言語でLinuxにおけるリアルタイムスケジューリングRMとEDFの実装

C言語でLinuxにおけるリアルタイムスケジューリングRMとEDFの実装を紹介します.

結構難しい内容なので,じっくり読み進めて下さい.

RMとEDFの理論や比較を知りたいあなたはこちらからどうぞ.

第7回リアルタイムシステム
【第7回】元東大教員から学ぶリアルタイムシステム「Rate Monotonicスケジューリング」

こういった私から学べます. 前回を読んでいない方はこちらからどうぞ. リアルタイムシステムの記事一覧はこちらからどうぞ. Rate Monotonic(RM)スケジューリング Rate Monoton ...

続きを見る

第8回リアルタイムシステム
【第8回】元東大教員から学ぶリアルタイムシステム「Earliest Deadline Firstスケジューリング」

こういった私から学べます. 前回を読んでいない方はこちらからどうぞ. リアルタイムシステムの記事一覧はこちらからどうぞ. Earliest Deadline First(EDF)スケジューリング Ea ...

続きを見る

第11回リアルタイムシステム
【第11回】元東大教員から学ぶリアルタイムシステム「RMとEDFの比較」

こういった私から学べます. 前回を読んでいない方はこちらからどうぞ. リアルタイムシステムの記事一覧はこちらからどうぞ. RMとEDFの比較 今回は,Rate Monotonic(RM)とEarlie ...

続きを見る

本記事では,以下の記事の内容を理解していることを前提とします.

C言語 スレッド
【C言語】スレッドの生成と実行【pthread,マルチスレッド,スレッドIDの取得】

こういった悩みにお答えします. こういった私から学べます. スレッド スレッドとは,OSにおけるプログラムの実行単位です. スレッドが管理する情報はプロセスより少ないので,スレッド間のコンテキストスイ ...

続きを見る

C言語 プロセス
【C言語】プロセスの生成と実行【fork/wait/execve/execl/getpid/getppid関数】

こういった悩みにお答えします. こういった私から学べます. プロセス プロセスとは,OSが管理するプログラムのインスタンスのことです. プロセス間ではメモリ空間を共有しませんが,同じプロセス内のスレッ ...

続きを見る

C言語 get_nprocs関数
【C言語】Linuxのプロセッサ数を取得するget_nprocs_conf/get_nprocs関数の使い方【CPUのホットプラグ】

こういった悩みにお答えします. こういった私から学べます. get_nprocs_conf/get_nprocs関数

get_npro ...

続きを見る

C言語 CPU_SET
【C言語】cpu_set_tデータ構造体とCPU_SETマクロの使い方

こういった悩みにお答えします. こういった私から学べます. cpu_set_tデータ構造体 cpu_set_tデータ構造体は,CPU集合を表現します. CPU集合は,どのCPUが何の操作を許可している ...

続きを見る

C言語 sched_*関数 tasksetコマンド
【C言語】sched_setaffinity/sched_getaffinity/sched_getcpu関数の使い方【tasksetコマンドでスレッドを特定のCPUで実行】

こういった悩みにお答えします. こういった私から学べます. 本記事では,以下の記事の内容を理解していることを前提とします. sched_setaffinity/sched_getaffinity/sc ...

続きを見る

sched_attr構造体とsched_setattr/sched_getattrシステムコール

sched_setattr/sched_getattrシステムコールは,スケジューリングポリシーと属性の設定と取得を行います.

これらのシステムコールはPOSIX非標準のもので,Linuxによる拡張であることに注意して下さい.

sched_attr構造体は,指定したスレッドの新しいスケジューリングポリシーと属性を定義した構造体で,sched_setattr/sched_getattrシステムコールの第2引数で利用します.

  • size:この構造体のサイズ
  • sched_policy:ポリシー(SCHED_*)
  • sched_flags:フラグ
  • sched_nice:nice値(SCHED_OTHER,SCHED_BATCH)
  • sched_priority:静的優先度(SCHED_FIFO,SCHED_RR)
  • sched_runtime:SCHED_DEADLINEの実行時間
  • sched_deadline:SCHED_DEADLINEの相対デッドライン
  • sched_period:SCHED_DEADLINEの周期
  • sched_util_min:SCHED_DEADLINEのCPU利用率の最小値
  • sched_util_max:SCHED_DEADLINEのCPU利用率の最大値

標準ライブラリのヘッダファイルsched.hにsched_setattr/sched_getattrシステムコールのプロトタイプ宣言とsched_attr構造体の定義があるという記載ですが,Ubuntu 22.04 LTSのヘッダファイルにはありません.

※sched_setattr/sched_getattrシステムコールは非標準のLinuxによる拡張であるからだと考えられます.

また,linux/sched/types.hヘッダファイルにsched_setattr/sched_getattrシステムコールのプロトタイプ宣言とsched_attr構造体の定義はありますが,linux/sched/types.hヘッダファイルをインクルードすると標準ライブラリのヘッダファイルsched.hとの整合性が取れていないため,ビルドエラーが発生します.

なので,自作コードでsched_attr構造体の定義とsched_setattr/sched_getattrシステムコールのプロトタイプ宣言が必要になりますので注意しましょう!

LinuxにおけるリアルタイムスレッドはCPUを100%利用できない!?

Linuxにおけるリアルタイムスレッドは,デフォルトではCPUを100%利用できない設定になっています.

catコマンドで実行すると以下のようになります.

  • sched_rt_period_usは1,000,000マイクロ秒(1秒)
  • sched_rt_runtime_usは950,000マイクロ秒(0.95秒)

つまり,リアルタイムスレッドは1秒あたり0.95秒までしか実行できません(1秒あたりのCPUの実行割合は95%).

この理由として,リアルタイムスレッドが暴走した場合の安全装置としての役割があるからです.(コアが1つしかない場合,そのコアでリアルタイムスレッドが暴走したらOSが制御不能になり,強制的に再起動しなければなりません.)

参考までに,上記の値はLinuxカーネルのkernel/core/sched.cファイルのsysctl_sched_rt_periodとsysctl_sched_rt_runtime変数に設定されています.

もしリアルタイムスレッドでCPUを100%利用したい場合は以下のコマンドを実行しましょう.

ここで,「sched_rt_runtime_us=-1」は無制限の意味です.

sched_rt_runtime_usを表示してみると,-1になっていることがわかります.

※この設定をした場合,実行するリアルタイムスレッドは注意して下さい.

LinuxにおけるRMとEDFの実装

LinuxにおけるRMとEDFの実装を紹介します.

RMはSCHED_FIFOスケジューリングポリシー,EDFはSCHED_DEADLINEスケジューリングポリシーを利用して実装します.

ここで,SCHED_FIFO/SCHED_DEADLINEスケジューリングポリシーは,管理者権限でないと利用できないことに注意して下さい(sudoコマンドで実行).

RMとEDFでスケジューリングするタスクセットは以下になります.

  • タスク数:2(RMを考慮してタスクIDが小さいほど周期が短いことを想定)
  • 実行時間は安全マージンを考慮して80%を実行(0.6秒の場合は0.6 * 80% = 0.48秒)
  • タスクセットの実行時間は3秒
  • RMの場合はタスクの実行するCPUはCPU 0で固定(migrate_thread_to_cpu関数でCPU 0にマイグレーション)
  • EDFはSCHED_DEADLINEの特性上,affinityマスクを設定できません(理由はこちら).特定のコアでSCHED_DEADLINEを実行したい場合は,以下の方法でLinuxが利用するコア数を1にしましょう!

CPUのホットプラグで動的にプロセッサを無効に設定する方法を知りたいあなたはこちらからどうぞ.

C言語 get_nprocs関数
【C言語】Linuxのプロセッサ数を取得するget_nprocs_conf/get_nprocs関数の使い方【CPUのホットプラグ】

こういった悩みにお答えします. こういった私から学べます. get_nprocs_conf/get_nprocs関数

get_npro ...

続きを見る

実装方法は以下の2種類を紹介します.

  • 1プロセス,マルチスレッドの実装
  • マルチプロセスの実装(コマンドラインでタスク数分のプログラムを実行)

コード一式は,こちらからrm_and_edf.zipをダウンロードして,解凍して下さい.

解凍したrm_and_edf.zipファイルの構成は以下になります.

  • Makefile:以下のRMとEDFの2種類の実装(合計4種類)をビルドするMakefile
  • fifo.c:RMの1プロセス,マルチスレッドの実装
  • fifo2.c:RMのマルチプロセスの実装(コマンドラインでタスク数分のプログラムを実行)
  • deadline.c:EDFの1プロセス,マルチスレッドの実装
  • deadline2.c:EDFのマルチプロセスの実装(コマンドラインでタスク数分のプログラムを実行)

以下のようにrm_and_edfディレクトリに移動してmakeでビルドすると,上記の4つのプログラムの実行ファイル(fifo,fifo2,deadline,deadline2)が作成されます.

1プロセス,マルチスレッドのRMの実装

1プロセス,マルチスレッドのRMの実装は以下になります.

実行結果は以下になります.

マルチプロセスのRMの実装(コマンドラインでタスク数分のプログラムを実行)

マルチプロセスのRMの実装(コマンドラインでタスク数分のプログラムを実行)は以下になります.

実行結果の例は以下になります.(プロセスIDは実行時により変動)

1プロセス,マルチスレッドのEDFの実装

1プロセス,マルチスレッドのEDFの実装は以下になります.

実行結果の例は以下になります.(実行するCPU IDは実行時により変動)

マルチプロセスのEDFの実装(コマンドラインでタスク数分のプログラムを実行)

マルチプロセスのEDFの実装(コマンドラインでタスク数分のプログラムを実行)は以下になります.

実行結果の例は以下になります.(プロセスIDや実行するCPU IDは実行時により変動)

まとめ

C言語でLinuxにおけるリアルタイムスケジューリングRMとEDFの実装を紹介しました.

具体的には,RMとEDFで,「1プロセス,マルチスレッド」と「マルチプロセス」の実装(合計4種類)を解説しました.

これらの4種類をゼロから実装するのは結構大変ですので,是非参考にして下さい.

C言語を独学で習得することは難しいです.

私にC言語の無料相談をしたいあなたは,公式LINE「ChishiroのC言語」の友だち追加をお願い致します.

私のキャパシティもあり,一定数に達したら終了しますので,今すぐ追加しましょう!

友だち追加

独学が難しいあなたは,元東大教員がおすすめするC言語を学べるオンラインプログラミングスクール5社で自分に合うスクールを見つけましょう.後悔はさせません!

-C LANGUAGE, TECHNOLOGY
-, , , , , ,