Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
Signed-off-by: Satoru Takeuchi <satoru.takeuchi@gmail.com>
  • Loading branch information
satoru-takeuchi committed Jul 3, 2022
1 parent 6ce83e4 commit 42835ff
Show file tree
Hide file tree
Showing 148 changed files with 14,194 additions and 0 deletions.
Binary file added 01-operating-system-overview/hello
Binary file not shown.
9 changes: 9 additions & 0 deletions 01-operating-system-overview/hello.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package main

import (
"fmt"
)

func main() {
fmt.Println("hello world")
}
3 changes: 3 additions & 0 deletions 01-operating-system-overview/hello.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/python3

print("hello world")
4 changes: 4 additions & 0 deletions 01-operating-system-overview/inf-loop
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/python3

while True:
pass
Binary file added 01-operating-system-overview/pause
Binary file not shown.
6 changes: 6 additions & 0 deletions 01-operating-system-overview/pause.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include <unistd.h>

int main(void) {
pause();
return 0;
}
6 changes: 6 additions & 0 deletions 01-operating-system-overview/syscall-inf-loop
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/python3

import os

while True:
os.getppid()
13 changes: 13 additions & 0 deletions 02-process-management-1/fork
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/python3

import os, sys

ret = os.fork()
if ret == 0:
print("子プロセス: pid={}, 親プロセスのpid={}".format(os.getpid(), os.getppid()))
exit()
elif ret > 0:
print("親プロセス: pid={}, 子プロセスのpid={}".format(os.getpid(), ret))
exit()

sys.exit(1)
14 changes: 14 additions & 0 deletions 02-process-management-1/fork-and-exec
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/python3

import os, sys

ret = os.fork()
if ret == 0:
print("子プロセス: pid={}, 親プロセスのpid={}".format(os.getpid(), os.getppid()))
os.execve("/bin/echo", ["echo", "pid={} からこんにちは".format(os.getpid())], {})
exit()
elif ret > 0:
print("親プロセス: pid={}, 子プロセスのpid={}".format(os.getpid(), ret))
exit()

sys.exit(1)
10 changes: 10 additions & 0 deletions 02-process-management-1/intignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/python3

import signal

# SIGINTシグナルを無視するように設定。第1引数にはハンドラを設定するシグナルの番号(ここではsignal.SIGINT)を、
# 第2引数にはシグナルハンドラ(ここではsignal.SIG_IGN)を指定する。
signal.signal(signal.SIGINT, signal.SIG_IGN)

while True:
pass
6 changes: 6 additions & 0 deletions 02-process-management-1/pause.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include <unistd.h>

int main(void) {
pause();
return 0;
}
6 changes: 6 additions & 0 deletions 02-process-management-1/spawn
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/python3

import os

os.posix_spawn("/bin/echo", ["echo", "echo", "posix_spawn()によって生成されました"], {})
print("echoコマンドを生成しました")
9 changes: 9 additions & 0 deletions 02-process-management-1/spawn-by-fork-and-exec
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/python3

import os

ret = os.fork()
if ret == 0:
os.execve("/bin/echo", ["echo", "fork()とexecve()によって生成されました"], {})
elif ret > 0:
print("echoコマンドを生成しました")
5 changes: 5 additions & 0 deletions 02-process-management-1/wait-ret
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

false &
wait $! # falseプロセスの終了を待ち合わせる。falseコマンドのPIDは`$!`変数から得られる
echo "falseコマンドが終了しました: $?" # wait後にfalseプロセスの戻り値は`$?`変数から得られる。
2 changes: 2 additions & 0 deletions 03-process-scheduler/src/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.data
*.jpg
57 changes: 57 additions & 0 deletions 03-process-scheduler/src/cpuperf
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/bin/bash

usage() {
exec >&2
echo "使い方: $0 [-m] <最大プロセス数>
1. 'cpuperf.data'というファイルに性能情報を保存する
* エントリ数は<最大プロセス数>
* 各行のフォーマットは'<プロセス数> <平均ターンアラウンドタイム[秒]> <スループット[プロセス/秒]>'
2. 性能情報をもとに平均スループットのグラフを作って'avg-tat.jpg'に保存
3. 同、スループットのグラフを作って'throughput.jpg'に保存
-mオプションはmeasureプログラムにそのまま渡す"
exit 1
}

measure() {
local nproc=$1
local opt=$2
bash -c "time ./multiload $opt $nproc" 2>&1 | grep real | sed -n -e 's/^.*0m\([.0-9]*\)s$/\1/p' | awk -v nproc=$nproc '
BEGIN{
sum_tat=0
}
(NR<=nproc){
sum_tat+=$1
}
(NR==nproc+1) {
total_real=$1
}
END{
printf("%d\t%.3f\t%.3f\n", nproc, sum_tat/nproc, nproc/total_real)
}'
}

while getopts "m" OPT ; do
case $OPT in
m)
MEASURE_OPT="-m"
;;
\?)
usage
;;
esac
done

shift $((OPTIND - 1))

if [ $# -lt 1 ]; then
usage
fi

rm -f perf.data
MAX_NPROC=$1
for ((i=1;i<=MAX_NPROC;i++)) ; do
measure $i $MEASURE_OPT >>cpuperf.data
done

./plot-perf $MAX_NPROC
4 changes: 4 additions & 0 deletions 03-process-scheduler/src/inf-loop
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/python3

while True:
pass
7 changes: 7 additions & 0 deletions 03-process-scheduler/src/load
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/python3

# 負荷の量を調整する値。お手元の環境ではtimeコマンド経由で実行したときに数秒程度になるように調整すると結果が見やすいです
NLOOP=100000000

for _ in range(NLOOP):
pass
49 changes: 49 additions & 0 deletions 03-process-scheduler/src/multiload
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/bin/bash

MULTICPU=0
PROGNAME=$0
SCRIPT_DIR=$(cd $(dirname $0) && pwd)

usage() {
exec >&2
echo "使い方: $PROGNAME [-m] <プロセス数>
所定の時間動作する負荷処理プロセスを<プロセス数>で指定した数だけ動作させて、すべての終了を待ちます。
各プロセスにかかった時間を出力します。
デフォルトではすべてのプロセスは1論理CPU上でだけ動作します。
オプションの意味:
-m: 各プロセスを複数CPU上で動かせるようにします。"
exit 1
}

while getopts "m" OPT ; do
case $OPT in
m)
MULTICPU=1
;;
\?)
usage
;;
esac
done

shift $((OPTIND - 1))

if [ $# -lt 1 ] ; then
usage
fi

CONCURRENCY=$1

if [ $MULTICPU -eq 0 ] ; then
# 負荷処理をCPU0でのみ実行できるようにします
taskset -p -c 0 $$ >/dev/null
fi

for ((i=0;i<CONCURRENCY;i++)) do
time "${SCRIPT_DIR}/load" &
done

for ((i=0;i<CONCURRENCY;i++)) do
wait
done
20 changes: 20 additions & 0 deletions 03-process-scheduler/src/plot-perf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/python3

import sys
import plot

def usage():
print("""使い方: sched <最大プロセス数>
* cpuperfプログラムの実行結果を保存した"perf.data"ファイルをもとに性能情報を示すグラフを作る。
* "avg-tat.jpg"ファイルに平均ターンアラウンドタイムのグラフを保存する。
* "throughput.jpg"ファイルにスループットのグラフを保存する。""".format(progname, file=sys.stderr))
sys.exit(1)

progname = sys.argv[0]

if len(sys.argv) < 2:
usage()

max_nproc = int(sys.argv[1])
plot.plot_avg_tat(max_nproc)
plot.plot_throughput(max_nproc)
73 changes: 73 additions & 0 deletions 03-process-scheduler/src/plot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#!/usr/bin/python3

import numpy as np
from PIL import Image
import matplotlib
import os

matplotlib.use('Agg')

import matplotlib.pyplot as plt

plt.rcParams['font.family'] = "sans-serif"
plt.rcParams['font.sans-serif'] = "TakaoPGothic"

def plot_sched(concurrency):
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
for i in range(concurrency):
x, y = np.loadtxt("{}.data".format(i), unpack=True)
ax.scatter(x,y,s=1)
ax.set_title("タイムスライスの可視化(並列度={})".format(concurrency))
ax.set_xlabel("経過時間[ミリ秒]")
ax.set_xlim(0)
ax.set_ylabel("進捗[%]")
ax.set_ylim([0,100])
legend = []
for i in range(concurrency):
legend.append("負荷処理"+str(i))
ax.legend(legend)

# Ubuntu 20.04のmatplotlibのバグを回避するために一旦pngで保存してからjpgに変換している
# https://bugs.launchpad.net/ubuntu/+source/matplotlib/+bug/1897283?comments=all
pngfilename = "sched-{}.png".format(concurrency)
jpgfilename = "sched-{}.jpg".format(concurrency)
fig.savefig(pngfilename)
Image.open(pngfilename).convert("RGB").save(jpgfilename)
os.remove(pngfilename)

def plot_avg_tat(max_nproc):
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
x, y, _ = np.loadtxt("cpuperf.data", unpack=True)
ax.scatter(x,y,s=1)
ax.set_xlim([0, max_nproc+1])
ax.set_xlabel("プロセス数")
ax.set_ylim(0)
ax.set_ylabel("平均ターンアラウンドタイム[秒]")

# Ubuntu 20.04のmatplotlibのバグを回避するために一旦pngで保存してからjpgに変換している
# https://bugs.launchpad.net/ubuntu/+source/matplotlib/+bug/1897283?comments=all
pngfilename = "avg-tat.png"
jpgfilename = "avg-tat.jpg"
fig.savefig(pngfilename)
Image.open(pngfilename).convert("RGB").save(jpgfilename)
os.remove(pngfilename)

def plot_throughput(max_nproc):
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
x, _, y = np.loadtxt("cpuperf.data", unpack=True)
ax.scatter(x,y,s=1)
ax.set_xlim([0, max_nproc+1])
ax.set_xlabel("プロセス数")
ax.set_ylim(0)
ax.set_ylabel("スループット[プロセス/秒]")

# Ubuntu 20.04のmatplotlibのバグを回避するために一旦pngで保存してからjpgに変換している
# https://bugs.launchpad.net/ubuntu/+source/matplotlib/+bug/1897283?comments=all
pngfilename = "avg-tat.png"
jpgfilename = "throughput.jpg"
fig.savefig(pngfilename)
Image.open(pngfilename).convert("RGB").save(jpgfilename)
os.remove(pngfilename)
67 changes: 67 additions & 0 deletions 03-process-scheduler/src/sched
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/usr/bin/python3

import sys
import time
import os
import plot

def usage():
print("""使い方: sched <プロセス数>
* 論理CPU0上で<プロセス数>の数だけ同時に100ミリ秒程度CPUリソースを消費する負荷処理プロセスを起動した後に、すべてのプロセスの終了を待つ。
* "sched-<プロセス数>.jpg"というファイルに実行結果を示したグラフを書き出す。
* グラフのx軸は負荷処理プロセス開始からの経過時間[ミリ秒]、y軸は進捗[%]""".format(progname, file=sys.stderr))
sys.exit(1)

# 実験に適した負荷を見つもるための前処理にかける負荷。
# このプログラムの実行に時間がかかりすぎるような場合は値を小さくしてください。
# 反対にすぐ終わってしまうような場合は値を大きくしてください。
NLOOP_FOR_ESTIMATION=100000000
nloop_per_msec = None
progname = sys.argv[0]

def estimate_loops_per_msec():
before = time.perf_counter()
for _ in range(NLOOP_FOR_ESTIMATION):
pass
after = time.perf_counter()
return int(NLOOP_FOR_ESTIMATION/(after-before)/1000)

def child_fn(n):
progress = 100*[None]
for i in range(100):
for j in range(nloop_per_msec):
pass
progress[i] = time.perf_counter()
f = open("{}.data".format(n),"w")
for i in range(100):
f.write("{}\t{}\n".format((progress[i]-start)*1000,i))
f.close()
exit(0)

if len(sys.argv) < 2:
usage()

concurrency = int(sys.argv[1])

if concurrency < 1:
print("<並列度>は1以上の整数にしてください: {}".format(concurrency))
usage()

# 論理CPU0上での実行を強制
os.sched_setaffinity(0, {0})

nloop_per_msec = estimate_loops_per_msec()

start = time.perf_counter()

for i in range(concurrency):
pid = os.fork()
if (pid < 0):
exit(1)
elif pid == 0:
child_fn(i)

for i in range(concurrency):
os.wait()

plot.plot_sched(concurrency)
Loading

0 comments on commit 42835ff

Please sign in to comment.