ゾンビプロセスを作る
ゾンビプロセスというものがありますが、どんな時にゾンビプロセスができるのかなんとなくしか知らなかったので、実際に作って観察してみることにしました。
以下のコードで検証します。
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> int main(int argc, char *argv[]) { pid_t pid; pid = fork(); if (pid == 0) { // 子プロセス execl("/bin/sleep", "sleep", "5", NULL); } else { // 親プロセス int status; // sleep(10); // exit(0); waitpid(pid, &status, 0); printf("PID %d has been finished; exit status: %d", pid, status); exit(0); } }
このプログラム自体がやっていることは、まず fork して、子プロセスは exec で 5 秒 sleep し、親プロセスは子プロセスの終了を待ち、終了したら PID とステータスコードを出力するというものです。(fork や exec についての解説は省略します。) この状態ではまだゾンビプロセスは生まれません。
では検証を始める前に、いくつか準備しておきましょう。
上記のコードを parent.c
として保存し、コンパイルします。
$ gcc -o parent parent.c
次に、各親子プロセスの様子を観察するために ps
を watch
しておきます。
これで 1 秒ごとのプロセスの状態が観察できます。
$ watch -n 1 'ps aux | grep -e parent -e sleep | grep -v grep'
それでは実行してみましょう。
検証 1: お行儀よく wait する
parent
を実行すると、以下のように親子両方のプロセスが出てきて、5 秒後に両方のプロセスが終了します。
username 33080 0.0 0.0 4268020 672 s001 S+ 8:17PM 0:00.00 sleep 5 username 33074 0.0 0.0 4268012 792 s001 S+ 8:17PM 0:00.00 ./parent
意図通り動いていますね。
検証 2: 親プロセスが wait せずにいきなり exit する
次に、exit()
のみコメントを外します。
... (snip) ... // sleep(10); exit(0); waitpid(pid, &status, 0); ... (snip) ...
再びコンパイルして実行すると、sleep
だけが表示され、5 秒後に終了します。
username 33080 0.0 0.0 4268020 672 s001 S+ 8:17PM 0:00.00 sleep 5
子プロセスは、親プロセスが死ぬと PID 1 のプロセス (init, systemd, launchd など) を新たな親プロセスとします。
そのため、parent
は子プロセスを産んですぐに死にますが、子プロセスは 5 秒 sleep した後にそのまま終了します。
これはゾンビプロセスではありません。
検証 3: 子プロセスが終了しても、親プロセスは wait も exit もしない
次に sleep()
のコメントも外します。
これにより、子プロセスが 5 秒で終了した後しばらくの間、親プロセスが wait も exit もせずにいる状態が作り出せます。
... (snip) ... sleep(10); exit(0); waitpid(pid, &status, 0); ... (snip) ...
再びコンパイルして実行すると、5 秒後に子プロセスが (sleep)
という状態になり、10 秒後に両方のプロセスが同時に終了します。
username 39933 0.0 0.0 0 0 s001 Z+ 8:17PM 0:00.00 (sleep) username 39932 0.0 0.0 4268012 792 s001 S+ 8:17PM 0:00.00 ./parent
子プロセスは 5 秒後に終了しますが、その直後は親プロセスがまだ sleep している状態です。 プロセスを管理しているカーネルは親プロセスがこの後 wait を呼ぶのかどうか、呼ぶとしたらいつ呼ぶのかわからないですから、子プロセスのステータスコードをいつまでも保持しておかなければなりません。 この状態になった子プロセスがゾンビプロセスです。
ps aux
コマンドでは、8 列目にプロセスのステータスが出ます。(sleep)
となっているプロセスが、Z+
というふうに、ゾンビプロセスであることが表されていますね。
ということで、fork したあとはちゃんと wait しないとゾンビプロセスが生まれてしまうことが無事確認できました。
MacBook Air 13'' Late 2018 と MacBook Pro 13'' Late 2018 のスペック比較
新 Macbook Air が出たので、Macbook Air と MacBook Pro (どちらも 13 インチ) のどちらを買えば良いかの判断のためにスペックの比較表を作った。
公式サイトの比較ページをもとに、特に気になるところを抜き出して、オプションを付けたときの値段やメリット・デメリットなども併記した。
https://www.apple.com/jp/mac/compare/results/?product1=macbook-air-retina-13&product2=macbook-pro-touchbar-13
なにか間違っている所や足りなそうなところがあればご指摘ください。
スペック | MacBook Air | MacBook Pro |
---|---|---|
画面サイズ | 13.3 インチ 2,560 x 1,600 |
13.3 インチ 2,560 x 1,600 |
Touch Bar | なし | あり |
CPU | 第8世代Intelデュアルコアプロセッサ 1.6GHzデュアルコアIntel Core i5 (I5-8210Y) (Turbo Boost 3.6GHz) => ¥156,800 |
2.3GHzクアッドコアIntel Core i5 (I5-8259U) (Turbo Boost 4.5GHz) => ¥198,800 2.7GHzクアッドコアIntel Core i7 (I7-8850H) (Turbo Boost 4.5GHz) => ¥231,000 (+ ¥33,000) |
薄さ | 0.41〜1.56 cm | 1.49 cm |
重さ | 1.25 kg | 1.37 kg |
メモリ | 8 GB => ¥156,800 16 GB => ¥178,800 (+ ¥22,000) |
8 GB => ¥198,800 16 GB => ¥220,800 (+ ¥22,000) |
ストレージ | (128GB => ¥134,800) 256GB => ¥156,800 512GB => ¥178,800 (+ ¥22,000) 1.5TB => ¥266,800 (+ ¥110,000) |
256GB => ¥198,800 512GB => ¥220,800 (+ ¥22,000) 1TB => ¥264,800 (+ ¥66,000) 2TB => ¥352,000 (+ ¥154,000) |
ディスプレイ | IPSテクノロジー搭載
|
|
輝度 | 300ニト | 500ニト |
カラープロファイル | 標準色 (フルsRGB) | 広色域 (P3)
|
バッテリー | 50.3Whリチウムポリマーバッテリー 最大12時間のワイヤレスインターネット閲覧 最大13時間のiTunesムービー再生 |
58.0Whリチウムポリマーバッテリー 最大10時間のワイヤレスインターネット閲覧 最大10時間のiTunesムービー再生 |
電源アダプタ | 30W USB-C | 61W USB-C |
USB-C ポート | 2 | 4 |
Bluetooth | Bluetooth 4.2 | Bluetooth 5.0
|
実践ドメイン駆動設計 - 第2章 ドメイン、サブドメイン、境界づけられたコンテキスト
実践ドメイン駆動設計 第2章のまとめです。
2.8 全体像
サブドメインと境界づけられたコンテキストのはたらき
- オンライン販売を例に考える
コアドメインに注⽬する
2.9 なぜそれほどまでに戦略的設計を重視するのか
- コラボレーションプロジェクトチームの例を考える
2.10 実世界におけるドメインとサブドメイン
- ドメインは問題空間と解決空間を持つ
問題空間
解決空間
- ソフトウェアをどのように実装してその課題を解決するかに注⽬する
- 解決空間 = 境界づけられたコンテキスト
- 境界づけられたコンテキスト
- 例えば、
- 特定のソリューションを表すもの
- 特定のソリューションを具現化したビュー
- 特定のソフトウェアモデルの集合
- 例えば、
- 境界づけられたコンテキストを⽤いて、何らかのソリューションをソフトウェアとして具現化する
問題空間と解決空間
- 各サブドメインを、境界づけられたコンテキストと⼀対⼀で対応させるのが望ましいゴール
- しかし実際は難しいので、アセスメントビューを使う (これ以上詳しい説明がなかった)
- ERP (Enterprise Resource Planning) アプリケーションを例として考えてみる
- 会計、プロジェクト管理、製造などの日々の業務を管理するために組織が使用するシステムおよびソフトウェアパッケージ
評価
- 問題空間 (ドメイン) の評価のための質問
- 解決空間 (境界づけられたコンテキスト) の評価のための質問
2.11 境界づけられたコンテキストの意味を知る
- 境界づけられたコンテキスト
- ドメインモデル
- ユビキタス⾔語をソフトウェアモデルとして表したもの
- なぜ "境界" が必要なのか?
- 各モデルの内部的な概念やプロパティ・操作がそれぞれ特別な意味を持つから
- 異なる⼆つのモデルが、同じ、あるいはよく似た名前のオブジェクトを違う意味で使っていることが多い
- ⼆つのモデルを明確に境界づけておくことで、それぞれのコンテキストにおける意味合いをはっきりさせる
- したがって、境界づけられたコンテキストは主として "⾔語的な境界" となる
- 巨大モデルの誘惑
コンテキスト
- 文脈
- 例えば、同じ「アカウント」という⽤語でも、銀⾏取引コンテキスト (口座) と⽂学コンテキスト (報告書) とでは意味合いがまったく異なる
- 実世界におけるコンテキスト
- 実際の業務でありがちなのは、似ているけれども微妙に意味が違うという状況
- なぜなら、各チームがそれぞれのコンテキストで選んだ名前は、そのユビキタス⾔語を念頭に置いて考えられているものだから
- 「アカウント」の例をもう少し
- 「当座預⾦⼝座」と「普通預⾦⼝座」の銀⾏取引コンテキストを考えてみる
- 当座預⾦コンテキストで使うオブジェクトに「当座預⾦⼝座」、普通預⾦コンテキストで使うオブジェクトに「普通預⾦⼝座」などとご丁寧に名づける必要はなく、単に「⼝座」と名づけられる
- それぞれの境界づけられたコンテキストが、微妙な意味の違いを区別する
- 名前を同一にしなければいけないという決まりがあるわけではないので、チームが判断すればよい
- 「当座預⾦⼝座」と「普通預⾦⼝座」の銀⾏取引コンテキストを考えてみる
- 境界づけられたコンテキスト間でのマッピング
- 通常は通常はオブジェクトのインスタンスを境界の外で使うことはないが、状態の一部を共有することがあるかもしれない
- あまり詳しい説明はなかった
- 通常は通常はオブジェクトのインスタンスを境界の外で使うことはないが、状態の一部を共有することがあるかもしれない
- 同一モデルの中の複数のコンテキスト
- 出版社の業務モデルの例
- 書籍の起案 -> 執筆と編集のプロセス管理 -> 装丁や挿絵をデザイン -> 他の言語に翻訳 -> 宣伝 -> 出荷
- これらを統一的に扱うモデルを使おうとしてしまうと混乱する
- 段階ごとに「書籍」の定義すら変わってくる
- 実際には、書籍オブジェクトにはおそらく識別⼦があって、それをコンテキスト間で共有するのだろう
- コラボレーションチームの例
- 重要なのは、"異なる概念やオブジェクトが、同じものであるともいえるし違うものだともいえるということで、その違いは、どの境界づけられたコンテキストで⾒るかによるということ"
- 出版社の業務モデルの例
モデル以外のものを扱う余地
- 境界づけられたコンテキストは、ドメインモデルだけを扱うものというわけでなはい
- システムやアプリケーション、あるいは業務サービスなどを区切るためにも使われる
- 利口なUI アンチパターン
- ビジネスロジックやデータアクセスのコードが、UI のコードと一緒になってしまっている状態
- すべての処理が UI の中で行なわれるので「利口な」UI と呼ばれる
境界づけられたコンテキストの⼤きさ
- 要点
- ドメインモデルの変更
- イテレーションのたびに、私たちはモデルに関する仮定と戦うことになる
- モデルに何らかの概念を追加したり削除したりする
- ここでのポイントは、何度も繰り返し問題に直⾯するということ
- DDD の原則に従っていれば、何がモデルに属して何がモデルに属さないのかをきちんと考察できるようになる!
- イテレーションのたびに、私たちはモデルに関する仮定と戦うことになる
- ドメインモデルの美しい⾳⾊
- 観念的すぎてわからん
- 境界づけられたコンテキストのサイズを間違えて作ってしまう原因
- 適切なサイズの境界づけられたコンテキストを作る時の留意点
技術的なコンポーネントとの協調
- 境界づけられたコンテキストを、技術的コンポーネントの観点で考えることは特に問題はないが、技術的コンポーネントがコンテキストを定めるのではないことに注意する
- Java での例
- 境界づけられたコンテキスト
com.mycompany.optimalpurchasing
- 責務による分割
com.mycompany.optimalpurchasing.presentation
com.mycompany.optimalpurchasing.application
com.mycompany.optimalpurchasing.domain.model
com.mycompany.optimalpurchasing.infrastructure
- このようにモジュール分割したとしても、単⼀の境界づけられたコンテキストの作業は単⼀のチームが受け持つべき
- 明確に境界づけられたコンテキストで作られたユビキタス⾔語にチームを注⼒させるため
- Java だと、境界づけられたコンテキストをひとつの JAR にまとめられる
- 境界づけられたコンテキスト
2.12 サンプルのコンテキスト
- 現実世界では、あらゆるプロジェクトに、境界づけられたコンテキストが複数存在するため、それらの統合が重要となる
- 例として、コラボレーションツール (G Suite や Confluence みたいなやつ) について、セキュリティや権限の情報をコラボレーションモデルに組み込んでしまうという間違いを犯してしまった、ということを考える
- どう改善するか?
- コンテキストマップを使い、現在の問題点を整理する
- [Evans] の「第4部:戦略的設計」で紹介されている? (未確認)
- これにより、現在の窮状を議論することで、建設的な分析で解決策を考えられるようになった
- 隔離されたコア [Evans] を⽬指す
- コンテキストマップを使い、現在の問題点を整理する
- 境界づけられたコンテキストを⼩さくするべく、いくつかの⼩さなコンテキストを切り出すことも考えられるが、これは良くない
SSIDonMenubar なるアプリケーションを作りました
現在つないでいるネットワーク名をメニューバーに表示する Mac 用のアプリケーションです。
こんな感じ
SSID をそのまま表示させると長くなりすぎるので最初の三文字しか表示させていない。
開発したモチベーションとしては、
自宅のネットワーク環境が携帯のテザリングなのですが、家でテザリングにつないでいて大学に来た後テザリングしていることに気づかず、うっかりでかいデータをダウンロードしたり YouTube とか見まくったりすると (なにしてんだ) あっという間に帯域制限がかかってしまうまで通信してしまうので、常にどの Wi-Fi につないでいるか気をつけておく必要がある。 でもいつもいつも Wi-Fi のアイコンをクリックして SSID を確認するのが面倒なので、メニューバーに現在つないでいるネットワーク名を表示する常駐アプリケーションを作ったという次第です。
たぶん自分にしか需要ないけどソースコードを公開します。
実は初めて Mac のアプリケーションを書いた && Swift 書いた。
date コマンドでタイムゾーンを指定する方法
方法: 環境変数 TZ を指定すれば良い。
例えば、東部夏時間 (Eastern Daylight Time; EDT) にしたければ以下のようにする。
env TZ="America/New_York" date
TZ に使える値は tzselect コマンドを使えばわかる。
例えば、アメリカの東海岸側のタイムゾーンが知りたければ、
$ tzselect
Please identify a location so that time zone rules can be set correctly.
Please select a continent or ocean.
1) Africa
2) Americas
3) Antarctica
4) Arctic Ocean
5) Asia
6) Atlantic Ocean
7) Australia
8) Europe
9) Indian Ocean
10) Pacific Ocean
11) none - I want to specify the time zone using the Posix TZ format.
#? 2
Please select a country.
1) Anguilla 28) Haiti
2) Antigua & Barbuda 29) Honduras
3) Argentina 30) Jamaica
4) Aruba 31) Martinique
5) Bahamas 32) Mexico
6) Barbados 33) Montserrat
7) Belize 34) Nicaragua
8) Bolivia 35) Panama
9) Brazil 36) Paraguay
10) Canada 37) Peru
11) Caribbean Netherlands 38) Puerto Rico
12) Cayman Islands 39) St Barthelemy
13) Chile 40) St Kitts & Nevis
14) Colombia 41) St Lucia
15) Costa Rica 42) St Maarten (Dutch part)
16) Cuba 43) St Martin (French part)
17) Curacao 44) St Pierre & Miquelon
18) Dominica 45) St Vincent
19) Dominican Republic 46) Suriname
20) Ecuador 47) Trinidad & Tobago
21) El Salvador 48) Turks & Caicos Is
22) French Guiana 49) United States
23) Greenland 50) Uruguay
24) Grenada 51) Venezuela
25) Guadeloupe 52) Virgin Islands (UK)
26) Guatemala 53) Virgin Islands (US)
27) Guyana
#? 49
Please select one of the following time zone regions.
1) Eastern Time
2) Eastern Time - Michigan - most locations
3) Eastern Time - Kentucky - Louisville area
4) Eastern Time - Kentucky - Wayne County
5) Eastern Time - Indiana - most locations
6) Eastern Time - Indiana - Daviess, Dubois, Knox & Martin Counties
7) Eastern Time - Indiana - Pulaski County
8) Eastern Time - Indiana - Crawford County
9) Eastern Time - Indiana - Pike County
10) Eastern Time - Indiana - Switzerland County
11) Central Time
12) Central Time - Indiana - Perry County
13) Central Time - Indiana - Starke County
14) Central Time - Michigan - Dickinson, Gogebic, Iron & Menominee Counties
15) Central Time - North Dakota - Oliver County
16) Central Time - North Dakota - Morton County (except Mandan area)
17) Central Time - North Dakota - Mercer County
18) Mountain Time
19) Mountain Time - south Idaho & east Oregon
20) Mountain Standard Time - Arizona (except Navajo)
21) Pacific Time
22) Pacific Standard Time - Annette Island, Alaska
23) Alaska Time
24) Alaska Time - Alaska panhandle
25) Alaska Time - southeast Alaska panhandle
26) Alaska Time - Alaska panhandle neck
27) Alaska Time - west Alaska
28) Aleutian Islands
29) Hawaii
#? 1The following information has been given:
United States
Eastern TimeTherefore TZ='America/New_York' will be used.
Local time is now: Tue Oct 27 17:24:28 EDT 2015.
Universal Time is now: Tue Oct 27 21:24:28 UTC 2015.
Is the above information OK?
1) Yes
2) No
#? ^C
これで TZ には America/New_York を指定すれば良いことがわかる。
HP ProLiant MicroServer Remote Access Card の Virtual KVM が起動できない問題
HP ProLiant MicroServer Remote Access Card の KVM (over IP) アプリケーションを起動しようとしたら、「ご使用のセキュリティ設定により、自己署名付きアプリケーションの実行がブロックされています」と怒られた。
どうも、Java 7 Update 51 以降、自己署名型証明書を使用したアプリケーションはデフォルトでブロックされるようになったらしい。*1
とりあえず信頼して起動するために、例外サイト・リストに追加する。
- [Javaコントロール・パネル] を開く
- [セキュリティ] タブ > [サイト・リストの編集]
- [例外サイト・リスト] > [追加]
- URL を入力する: https://host[:port] > [OK]
これだけだとまだ起動出来なくてなぜかなーと思ったら、JNLP ファイルのリソースに指定されてる URL が HTTP のものになってるではないか。これを修正する。
*1:Javaからセキュリティ・プロンプトが表示される場合はどうすればよいですか。: https://www.java.com/ja/download/help/appsecuritydialogs.xml
PukiWiki Advance インストール時のメモ
PukiWiki Advance という、PukiWiki の派生の PukiWiki Plus! のさらに派生のウィキクローンがあります。
これを次の環境にインストールしたメモです。
PukiWiki Advance 自体は PukiWiki Advance - SourceForge.JP からダウンロードするか、git clone します。ただ、git clone の場合はクローン後に外部ファイルのインストールをする必要があり、自分はそこでエラーが出てしまったので PukiWiki Advance - SourceForge.JP からダウンロードしなおしました。
で、適当な場所に配置したのですが、SQLite の PDO ドライバがないと怒られます。
Fatal error: Uncaught exception 'PDOException' with message 'could not find driver' in pukiwiki_path/vendor/bad-behavior/bad-behavior-sqlite.php:174 Stack trace: #0 pukiwiki_path/vendor/bad-behavior/bad-behavior-sqlite.php(174): PDO->__construct('sqlite:pukiwiki_path...') #1 pukiwiki_path/vendor/bad-behavior/bad-behavior-sqlite.php(228): bb2_install() #2 pukiwiki_path/wiki-common/lib/init.php(56): require('pukiwiki_path...') #3 pukiwiki_path/wiki-common/lib/main.php(100): require('pukiwiki_path...') #4 pukiwiki_path/webroot/index.php(46): require('pukiwiki_path...') #5 {main} thrown in pukiwiki_path/vendor/bad-behavior/bad-behavior-sqlite.php on line 174
まず共有モジュールががインストールされているかどうか、extension_dir を確認します。
$ php -i | grep extension_dir extension_dir => /usr/lib/php5/20121212 => /usr/lib/php5/20121212 $ ls /usr/lib/php5/20121212 json.so mysqli.so mysql.so opcache.so pdo_mysql.so pdo.so pdo_sqlite.so readline.so
ない。ので、インストールします。
$ sudo apt-get -y install php5-sqlite
インストールが終わったら Apache を再起動します。
$ sudo service apache2 restart
あとは、細々と出てくる権限周りのエラーを地道に潰していけば OK です (あまり OK 感がしない)。