差分

移動先: 案内検索

プロセス管理

58 バイト追加, 2022年8月18日 (木) 18:55
/* プライオリティ */
Linuxカーネルが扱えるプロセスIDの最大値は/proc/sys/kernel/pid_maxを参照すればわかります。
カーネルの[https://github.com/torvalds/linux/blob/master/include/linux/threads.h ソースコード]内ではプロセスIDの最大値は次のようにして設定しています。
最少構成でカーネルを作った場合は4096、32ビットCPUだと32768、64ビットもしくはそれ以上のCPUだと68293696ということになります。最少構成でカーネルを作った場合は4096、32ビットCPUだと32768、64ビットもしくはそれ以上のCPUだと4 * 1024 * 1024つまり4194304ということになります。
<syntaxhighlight lang='C' line="1" >
<pre class="C">
/*
* This controls the default maximum pid allocated to a process
(sizeof(long) > 4 ? 4 * 1024 * 1024 : PID_MAX_DEFAULT))
</syntaxhighlight pre>
プロセスの生成は[http://man7.org/linux/man-pages/man2/fork.2.html fork(2)]を使い親プロセスが子プロセスを生み出します。下のコードを見て下さい。
 <syntaxhighlight langpre class='"C' line="1" >
#include <unistd.h>
#include <stdlib.h>
return(0);
}
</syntaxhighlight pre >
システムコールfork(2)はフォーク後、親プロセスでは子プロセスのプロセスIDを返却し、子プロセスでは0を返却します。
<syntaxhighlight langpre class='"C' line="1" >
#include <unistd.h>
#include <sys/types.h>
wait(&wstat);
}
</syntaxhighlightpre>
;調べてみよう: カーネルの中でforkをするのはkernelカーネルの中でforkをするのは[https://github.com/torvalds/linux/blob/master/kernel/fork.cの中の関数do_fork です。関数do_forkは関数copy_processを呼び出してプロセスをコピーするのがメインの役割です。関数copy_processは、必要なものを親プロセスからコピーし子プロセス独自に必要な情報を初期化しています。c#L2541 kernel_clone()]です。それまでは_do_fork()でしたが2020年にリリースされたLinux Kernel 5.9以降kernel_clone()になりました。[https://patchwork.kernel.org/project/linux-kselftest/cover/20200818173411.404104-1-christian.brauner@ubuntu.com/#23554325 参考資料]
==== プロセスを生成するシステムコール ====
プロセスにCPU資源をどのように与えるかの順番を決めるスケジュール (schedule)ことを行うことがスケジューリング(scheduling)です。それを司るのがスケジューラ(scheduler)<ref>Linux Schedulerhttps://www.kernel.org/doc/html/latest/scheduler/index.html</ref>です。
==== 基本的なスケジューリング方式 ====
==== 使えるスケジューリングを調べてみる ====
 
その後 Linux 3.14 (2014/3/20リリース) からリアルタイム指向の処理に必要なデットラインを処理するための [https://core.ac.uk/download/pdf/14699805.pdf SCHED_DEADLINE] がスケジューラ <ref> デフォルトで使えるかどうかはディストリビューションによります。</ref> に加わっています。Linux 3.14ではデットライン・スケジューラのアルゴリズムはEarliest Deadline First (EDF)を採用していましたが、Linux 4.13 (2017/9/5リリース)からはEDFを改良しさらに Constant Bandwidth Server ( CBS ) 加えた( と、 [https://uc2.h2np.net/src/deadline_c.html#N1 カーネルのコメント] では表現している )アルゴリズムを採用しています。
またchrtはプロセスのスケジューリング・ポリシーを変更することが出来ます。詳しくはマニュアル [https://man7.org/linux/man-pages/man1/chrt.1.html chrt] を確認してください。
 
 
;追記: その後 Linux 3.14 (2014/3/20リリース) からリアルタイム指向の処理に必要なデットラインを処理するための [https://core.ac.uk/download/pdf/14699805.pdf SCHED_DEADLINE] がスケジューラ <ref> デフォルトで使えるかどうかはディストリビューションによります。</ref> に加わっています。Linux 3.14ではデットライン・スケジューラのアルゴリズムはEarliest Deadline First (EDF)を採用していましたが、Linux 4.13 (2017/9/5リリース)からはEDFを改良しさらに Constant Bandwidth Server ( CBS ) 加えた( と、 [https://github.com/torvalds/linux/blob/master/kernel/sched/deadline.c カーネルのコメント] では表現している )アルゴリズムを採用しています。
 
Linux 2.6.23からCFS(Completely Fair Scheduler)
<ref>
Inside the Linux 2.6 Completely Fair Scheduler
https://developer.ibm.com/tutorials/l-completely-fair-scheduler/
(リンク切れ)
Linux カーネル 2.6 Completely Fair Scheduler の内側
http://www.ibm.com/developerworks/jp/linux/library/l-completely-fair-scheduler/
</ref>
<ref>Completely Fair Scheduler によるマルチプロセッシングhttp://www.ibm.com/developerworks/jp/linux/library/l-cfs/index.html</ref>は、Oは、O(1) スケジューラがヒューリスティック(発見的)にスケジューリングしていたのに対し、CFS のスケジューリングは(数学的な意味で)数値を計算してスケジューリングを決めます。
ヒューリスティックな方法では、ある種の特定の条件に嵌まってしまいスケジューリングが公平に処理できなくなったり、あるいは偶然に有利な条件になったり不利な条件になったりとする可能性があります。
それに比べCFSは公平にスケジューリングされます。
=== プライオリティ ===
UNIX系のオペレーティングシステムではプロセスの持つ動的に変化するプライオリティ値によって、CPUの割当てが変化します。プライオリティ値が小さいものが実行優先順位が高く、大きいものが実行優先順位が低くなります。UNIX系のオペレーティングシステムではプロセスの持つ動的に変化するプライオリティ値によって、CPUの割当てが変化します。プライオリティ値が小さいものが実行優先順位が低く、大きいものが実行優先順位が高くなります。
プロセス待機キューの並べ変え、プロセスのタイムスライスの値を設定する時に、プライオリティが高い程、よりCPUが割り当てられるような計算がされます。
* fork版
<syntaxhighlight langpre class='"C' line="1" >
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>int main(void) { int i,stat;
for(i=0;i<1000;i++) {
if ( fork() == 0 ) {
_exit(0);
}
wait(&stat);
}
printf("%d\n",i);
}
</syntaxhighlightpre
<pre class="bash">
% cc -O fork.c -o f
* thread版
<syntaxhighlight langpre class='"C' line="1" > 
#include <pthread.h>
#include <stdlib.h>
printf("%d\n",i);
}
</syntaxhighlightpre>
<pre class="bash">
% cc -O thread.c -lpthread -o t