タグ

forkに関するakaneharaのブックマーク (12)

  • Go言語で知るプロセス(2)

    前回の記事では、プログラムの実行単位であるプロセスについて、さまざまな属性やリソースをGo言語の視点から紹介しました。 今回は、Go言語のプログラムから、他のプロセスを実行したり属性を変更したりする方法を紹介します。 Go言語のプログラムから他のプロセスを扱うときは、プロセスを表す構造体を利用します。 そのための構造体には次の2種類があります。 osパッケージのos.Process: 低レベルな構造体 os/execパッケージのexec.Cmd: 少し高機能な構造体。内部でos.Processを持つ まず高機能で実用的なexec.Cmdの使い方を説明してから、os.Processの使い方を簡単に紹介します。 その後、プロセスに関する便利なGo言語のライブラリを紹介します。 exec.Cmdによるプロセスの起動 exec.Cmd構造体は次の2つの関数で作ることができます。 exec.Comm

    Go言語で知るプロセス(2)
  • fork/execモデルの起源 - Plan9日記

    UNIXを勉強すると、forkとexecが分離されていることに疑問を持ち、パイプやリダイレクトを使ってシェルを作り、その合理性に感動するというのが、お決まりのパターンになっているが、なぜこんな実装が生まれてきたのだろう。 WindowsのネイティブAPIであるNtCreateProcessや、その祖先とも言える*1VMSのsys$creprcは、意味的にはforkとexecが一体化されている。まぁ、こっちの方がプロセス生成という意味では自然なアプローチに感じられるが、sys$creprcの山のような引数を見ると、これを使ってプログラムを書く気は萎えてくる。input、output、errorって標準入出力のバインディングを変えるためだろうか。そうだとすると、UNIXモデルの方がシンプルで理に適っている。 fork、execはUNIX V1のころから存在するのだが、「The Evolutio

    fork/execモデルの起源 - Plan9日記
  • forkしたプロセスから共有するファイルディスクリプタへの書き込みについて

    ファイルを開いてからforkすると、そのファイルディスクリプタはシステムワイドなオープンファイルテーブルの同じ項目を指すので、書き込み位置(file offset)も共有され、同時に追加書き込みをしても競合は発生しないと思ったのですが、実験してみたら log.txt PARENT 24043 894 helloCPARENT 24043 895 hellCHPARENT 24043 896 helCHIPARENT 24043 897 heCHILPARENT 24043 898 hello のようにおかしな部分が出ていました。環境はLinux 3.10.0です。 基礎的なことかと思いますが、どうしてこうなるのか教えていただけないでしょうか。 実験に使ったコード: #include <stdio.h> #include <unistd.h> #include <fcntl.h> #incl

    forkしたプロセスから共有するファイルディスクリプタへの書き込みについて
  • 親プロセスは2度死ぬ - デーモン化に使うダブルforkの謎 - シリコンの谷のゾンビ

    デーモンプロセスを作る場合には,教科書によく書かれている2度forkは不要ではないか? ということを以前の記事に書いた. [c][unix]UNIXネットワークプログラミングのお勉強 (2) デーモンの作り方 - 睡眠不足?! 確かにBSDのdaemon(3) のコードでは,forkは1回しか呼んでいない. 「きっとプレセスがセッションリーダだと不都合があるのだろう.でもなぜ?」 というのがopen questionだった. それに対する答えを「詳解UNIXプログラミング」[1] に見つけた. SVR4においては,この時点でforkを再度呼び,親を終了することを勧める人がいる. 2番目の子がデーモンとして動作する.これは,デーモンはセッションリーダではなく, SVR4の規則 (9.6節) から,セッションリーダでなければ制御端末を取得できない,ということを保証する. あるいは,制御端末を取

    親プロセスは2度死ぬ - デーモン化に使うダブルforkの謎 - シリコンの谷のゾンビ
  • 特定条件下のclone(2)を4倍速くする - 人間とウェブの未来

    とあるサーバで妙にシステムCPUの使用率が高い現象が置きておりました。 そこで、まずはざっくりとperf topでプロファイルをとってみると、以下のようになっていました。 22.38% [kernel] [k] copy_pte_range 18.44% [kernel] [k] zap_pte_range 11.13% [kernel] [k] change_pte_range 3.58% [kernel] [k] page_fault 3.32% [kernel] [k] page_remove_rmap また、各プロセスのstraceを眺めていると、cloneで0.05秒とかなり時間がかかっているようです。これだと単純計算で1コアで秒間20回のcloneでコア100%占有してしまう程度の非常に低速な処理しかできないことになります。 sudo strace -T -o/dev/stdo

    特定条件下のclone(2)を4倍速くする - 人間とウェブの未来
  • Linux のプロセスが Copy on Write で共有しているメモリのサイズを調べる

    Linux は fork で子プロセスを作成した場合、親の仮想メモリ空間の内容を子へコピーする必要があります。しかしまともに全空間をコピーしていたのでは fork のコストが高くなってしまいますし、子が親と同じようなプロセスとして動作し続ける場合は、内容の重複したページが多数できてしまい、効率がよくありません。 そこで、Linux の仮想メモリは、メモリ空間を舐めてコピーするのではなく、はじめは親子でメモリ領域を共有しておいて、書き込みがあった時点で、その書き込みのあったページだけを親子で個別に持つという仕組みでこの問題を回避します。Copy-On-Write (CoW) と呼ばれる戦略です。共有メモリページは、親子それぞれの仮想メモリ空間を同一の物理メモリにマッピングすることで実現されます。より詳しくは コピーオンライト - Wikipedia などを参照してください。 この CoW に

    Linux のプロセスが Copy on Write で共有しているメモリのサイズを調べる
  • コンピューター:C言語講座:fork,exec,pipeについて

    コンピューター:C言語講座:fork,exec,pipeについて このテーマはどちらかというとUNIX系の話題になってしまうのですが、PC系ではDOSの時代にはマルチタスクができませんでしたので、平行には走れませんでしたが、C言語の処理系独自の関数がたくさんありました。WindowsになってからはUNIX系と似てきましたが、まだ少し違うようです。 自分で作成したプログラムから他のコマンドを実行したい、ということは良くあることだと思います。例えば、ディレクトリーの中身を簡単に得たい場合などはUNIXではlsコマンドを実行させて、結果をもらうのが簡単に思い付くと思います。とくにUNIXのコマンドはそのように組み合わせて使いやすくできていて、必要な情報だけを明確に返答するコマンドがほとんどです(その分、初心者が自分でコマンドを使う時に不親切なのですが)。 system() 大抵の人が上記のような

  • そこまで遅くないShellスクリプトの書き方

    この記事は Shell Script Advent Calendar 2015 10日目の記事です。 9日目の記事はryoana14さんの麗しきawkの世界でした。 Shellスクリプトがいつまで経ってもまともに書けないMasWagです。書けないなりにも人の書いた(昔の自分が書いたものも多く含む)スクリプトを見てこれは遅いなと思うことはたまにあります。書き方のコツというか考え方が幾つかあると思うのでまとめてみようと思います。基的な話なので多分Shellスクリプトをあんまり普段書かない人向けだと思います。ShellはBashを前提として書きます。zshだともっと色々できるのかもしれないです。細かい説明は(そんなに細かくなくても?)省いているので適宜manやinfoを参照すると良いでしょう。 forkを減らす Shellでコマンドを使うということは多くの場合プロセスをforkしていることにな

  • https://github.com/Shinpeim/process-book/blob/master/006.md

    https://github.com/Shinpeim/process-book/blob/master/006.md
  • Linux 環境でマルチコア CPU を利用した python プログラムを書く / 桃缶食べたい。

    Linux 環境でマルチコア CPU を利用した python プログラムを書く マルチコア CPU を利用した python プログラム、と言っても、Linux 環境ではプロセス単位で CPU が割り当てられるので、つまりはマルチプロセスを意識したプログラミングになります。 java でマルチコア CPU を利用しようとするとマルチスレッドで実現することになりますが、python の場合はわかりやすく別プロセスで実現されているため、ps や top コマンドで見えて面白いです。 python ではマルチプロセス用に multiprocessing モジュールが用意されていますが、今回はひとまず古典的な fork() 関数を使い、実際に複数のプロセスがマルチコア CPU によって処理されている様子を見てみたいと思います。 どちらかというと新人さん向けのプロセスのお話になってしまいましたが、

  • forkを攻略しよう 〜第2回〜 - Mandy Code

    筆が遅くてすいません・・・fork第2回です。 前回はforkで全く同じプロセスが2つ出来るよーという話をしました。 しかし前回のままでは子プロセス生成したらしっぱなしで、その状態やらをハンドリングすることは出来ません。 さらに子プロセスは終了してもそのままではプロセステーブルから削除されず、いわゆる「ゾンビプロセス」の状態になります。 そこで登場するのがwait関数です。 これはwaitシステムコールを行うもので、wait()で任意の子プロセスが終了するまで待ち、回収をします。(正確にはSIGCHLDシグナルが発生するまで待つ) 返り値はwait()が成功した場合は回収したプロセスのID、失敗した場合は-1となります。 これを使ってみます。 #!/usr/bin/env perl use strict; use warnings; my $pid = fork(); if ($pid)

    forkを攻略しよう 〜第2回〜 - Mandy Code
  • fork()は失敗するんだぜ、覚えときな

    fork() can fail: this is important あー、fork()のことね。プロセスがもっとプロセス作るためのやつな。いや、他にもプロセス作る方法はあるけどな。ま、面白い話がもうひとつあるから聞かせてやるよ。 forkは失敗するんだぜ。分かってるか? マジで分かってるか? マジだぜ。forkは失敗するもんだ。mallocと同じさ。失敗することもある。そんなに頻繁にってわけじゃないけどさ、でも失敗したら、無視できっこないぜ。ちっとは脳みそ働かせなきゃならん。 forkが0を返したら、そいつは子プロセスで、親なら正数を返すってことは、みんな知ってるよな。その値は子のpidだ。こいつを保存しといて、あとで使うってわけだ。 失敗を確認しない場合どうなるか知ってるか? そうだよ。お前多分、"-1"(forkのエラー通知)をpidとして扱ってるんだろ。 さて、問題の始まりだ。

  • 1