gitの基本概念

gitの基本概念

参考文献

入門Git

はじめに

この記事は入門Gitをテキストとした学習した記録です。

この記事は上記参考文献を読んでの筆者の解釈なので内容についての誤った記述がある可能性があります。

とても面白い本なのでおすすめです。下記内容について詳しく書かれています。

リビジョン

リビジョンとはある時点でのプロジェクト(ファイル群)の状態のこと。コミットとも呼ぶ。

コミット

コミットは上記の意味に加えて、あるリビジョンに基づいてそれに変化を加えて別のリビジョンを作ることを意味する動詞としても使われる。

ブランチ

ブランチとは開発の文脈に応じてコミットを指し示すポインターである。そのポインターが向けられているコミットがその文脈における先頭と見なされる。

ワークツリー

リビジョンに記録されている内容はオブジェクトによって呼び出すことができる。 リビジョンではファイルは圧縮されて管理されているのでそれを編集・閲覧するにはファイルシステムの特定の領域に展開する必要がある。その領域のことをワークツリーと呼ぶ。リビジョンを選択しワークツリーに展開することをcheckoutという。ワークツリーでの作業は下記のようになる。

  1. ワークツリーにリビジョンを展開する(checkout)。
  2. ワークツリーでファイルの編集を行う。
  3. 新しいリビジョンを作る(commit)。同時にブランチのポインターが新しいリビジョンに向けられる。

3-wayマージ

マージとはあるブランチのリビジョンに別のブランチのリビジョンを統合する作業のこと。

このマージに用いられるのが3-wayマージと呼ばれるアルゴリズムである。

feature/Afeature/Bをマージする場合下記のような操作が行われる。

  1. 二つのブランチで共通するコミットのうち最新のもの(common ancestor)を選ぶ。
  2. 1とAとの差分(変更点)を算出する。
  3. 1とBとの差分(変更点)を算出する。
  4. 2と3を比較しそれぞれの変更点を取り入れて状態を決定する。

4での状態の決定方法は下記のようになる。

  • 同一変更点はそれを採用する。
  • 片方のみ変更している部分はその変更を採用する。
  • 上記以外の変更点は競合(conflict)扱いとする。

ABのそれぞれの変更がどのように行われたか(コミット履歴の時間や方法や理由)は考慮しない。それらの最新のコミットとcommon ancestorのみを見て状態を決定する。

標準Cライブラリ

標準Cライブラリ

はじめに

この記事は下記の参考資料を元にした筆者の解釈の記述です。

正確さについては保証されませんので詳しくは参考元をご参照ください。

標準Cライブラリとは

C言語にはISO(国際標準化機構)によって定められた標準ライブラリがある。

Linuxでも標準Cライブラリが提供されている。

つまり標準Cライブラリは通常OSによって用意されるものである。

GNUが提供するglibcと呼ばれる標準Cライブラリが使用されることが多い。

ほとんどのCプログラムはglibcをリンクしている。

glibcシステムコールをラップする関数を含んでおり、POSIXに定義される関数も用意している。

リンクとは

C言語で書かれたプログラムを実行するためにはソースコードコンパイルアセンブリ言語にした後アセンブラと呼ばれるソフトウェアによってマシン語に変換する。

C言語で書かれたプログラムをソースプログラムと呼びビルドされたマシン語をオブジェクトプログラムと呼ぶ。

マシン語はその後リンク処理をされてから実行される。

リンクとはライブラリで提供されているプログラムを実行対象のプログラムに取り入れることである。

リンクはマシン語の時点で行われることからライブラリで提供されるプログラムもオブジェクトプログラムであることがわかる。

lddコマンド

Linuxではlddコマンドでプログラムがリンクしているライブラリを確認することができる。

$ ldd /bin/ls
        linux-vdso.so.1 =>  (0x00007ffee45c4000)
        libselinux.so.1 => /usr/lib64/libselinux.so.1 (0x00007f793567b000)
        libcap.so.2 => /lib64/libcap.so.2 (0x00007f7935477000)
        libacl.so.1 => /lib64/libacl.so.1 (0x00007f793526e000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f7934ea0000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f7934c9c000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f793589c000)
        libattr.so.1 => /lib64/libattr.so.1 (0x00007f7934a98000)

ライブラリの種類とリンクの方法

リンクのタイミングについては3種類がある。

  • 静的リンク
    • ビルド時
  • 動的リンク
    • 実行時
  • 動的ロード
    • 任意でのライブラリのロード時

ビルド時にリンクされるライブラリに拡張子は.aで動的リンク・動的ロードの拡張子は.so である。

soはShared Objectの略である。

POSIXとは

POSIX(Portable Operating System Interface)とはUNIX系OSに求められるAPIファイルシステムなどの規格をまとめたものである。

ファイルのパーミッションを確認する

[PHP]ファイルのパーミッションを確認する

areFileperms

ファイルのパーミッションを確認する。

ファイルへのパス(filename)を文字列で渡してパーミッション(perms)を 0777 などの8進数で渡す。

また、対象のファイル情報についてキャッシュを削除したい場合はrefreshをtrueとする。

返り値はboolean。 対象のファイルが指定のパーミッションであった場合にtrueとなり、そうでなければfalseとなる。

filepermsOctStr

ファイルのパーミッションを8進数の文字列で取得する。

対象のファイル情報についてキャッシュを削除したい場合は refresh を true とする。

コード

<?php

function areFileperms($filename, $perms, $refresh = false)
{
    $mode  = filepermsOctStr($filename, $refresh);
    $perms = sprintf('0%o', $perms);

    return $mode === $perms;
}

function filepermsOctStr($filename, $refresh = false)
{
    if ($refresh) {
        clearstatcache();
    }

    if (!$perms = fileperms($filename)){
        return '';
    }

    return substr(decoct($perms), -4);
}

ポイント

PHPでは8進数は先頭に0をつけることでこれを表す。

decoctの返り値は文字列。

filepermsなどファイルの情報を取得する関数では内部でシステムコールstatを呼んでおり、PHPがその結果をキャッシュしている。

PHP5.6ではこのキャッシュの結果がchmod関数でクリアされずパーミッションを変更した後でfilepermsを行っても初めにfilepermsを実行した時点の結果が戻り続けた。

これを解消するためにはclearstatcacheを行ってキャッシュをクリアすれば良いことがわかった。

参考

仮想メモリ空間

仮想メモリ空間

はじめに

この記事は下記の参考資料を元にした筆者の解釈の記述です。

正確さについては保証されませんので詳しくは下記の参考元をご参照ください。

仮想メモリとは

アプリケーションなどのプログラムは常に主記憶装置にロードされた上で実行される。

ロードされたプログラムの実行はプロセスという単位で管理される。

システムは複数のプロセスを同時に処理する必要がある場合があり、それが可能なシステムをマルチタスクと呼ぶ。

実際には一つのCPUが同じ瞬間に別のプロセスを実行することはできないので、プログラムは細かな単位に分けられて(プロセススケジューラにより)実行される。

このプロセス切り替えのことをコンテキストスイッチとよぶ。

コンテキストスイッチを十分に速く行うためには主記憶装置に同時に複数のプログラムがロードされている必要がある。

同じメモリ上に互いに無関係な複数のプログラムがロードされていて、かつそれらが互いにデータを参照できるような仕組みでは問題があるため、それらを明確に分けて管理するための仕組みが必要である。

その仕組みが仮想メモリと呼ばれるものである。

仮想メモリでは複数のプロセスが物理的に同じメモリを共有しているものの論理的にそれらの使用できる領域を分けて管理し、互いに干渉することを防ぐ仕組みである。

セグメント

プログラムがメモリにロードされる際は各データはセグメントと呼ばれる領域に分けてロードされる。

  • OSのカーネル領域
    • 全てのプログラムを最終的に実行するカーネルの領域。
    • プログラムからアクセスすることはできない。
  • テキストセグメント
    • プログラムの命令を格納する領域
  • データセグメント
    • プログラムのうちデータを格納する領域
      • 読み込み専用データ(定数)
      • 静的読み書き領域(静的変数)
      • 動的読み書き領域(ヒープ)
        • プログラムからカーネルに割り当てを要求して獲得される領域
  • スタックセグメント
    • プログラムの実行中に自動的に使用される領域
      • 関数からの戻り先アドレスなどスタックを使って管理されるデータ。

キューとスタック

キューとスタック

はじめに

この記事は下記の参考資料を元にした筆者の解釈の記述です。

正確さについては保証されませんので詳しくは下記の参考元をご参照ください。

データ格納方式

バッファにデータを格納する際の代表的な方式がキューとスタックの二種類である。

キュー

FIFO(first in first out)とも呼ばれる。

queueは日本語にすると待ち行列と言う意味。

データが入ってきた順番通りに処理される。

スタック

FILO(first in last out)とも呼ばれる。

プログラム実行時の変数を格納したり、関数呼び出し時の戻るべきアドレスを格納したりする際に使用する。

キューに比べてスタックを使用する場面は想像しづらいが、スタックでは処理の流れのネストした部分などをうまく表現することができる。

バッファ

バッファ

はじめに

この記事は下記の参考資料を元にした筆者の解釈の記述です。

正確さについては保証されませんので詳しくは下記の参考元をご参照ください。

バッファとは

コンピュータ内部や外部のネットワークには物理的な制約によって処理速度や転送速度のギャップが数多く存在している。

これらのギャップが解消されないまま処理を行おうとするとボトルネックとなる処理でデータが溢れて消えてしまうことになる。

そこで速度差が生じる部分にはそれを吸収・変換する仕組みが必要となる。 そのもっとも一般的な方法がバッファである。

例えばCPU(速い)とRAM(遅い)の間にはキャッシュメモリと呼ばれるバッファ記憶装置が置かれている。

バッファにも当然サイズがあるはずなので変換しきれない量のデータが速い装置から遅い装置に流れるとバッファが溢れる状態になることがある。

フロー制御

バッファが溢れてデータが失われることのないようにフロー制御を行うことがある。 バッファが一杯になった時にフローを中断する仕組みである。 この場合でもどこかにはデータをバッファする必要はあると思う。

TCP/IPの場合はTCPがフロー制御を行う。

TCPのフロー制御

TCPはデータを送る先のコンピュータの状態を見て処理が追いつかなそうな場合にそいつがデータを溢れさせることが無いように制御しながらパケットを送信している。

この場合にTCPがデータを保管しているのはバッファではなく、テンポラリ(tmp)と呼ばれる領域で後で使用するデータを一時保管するための場所である。

APIについて

APIについて

はじめに

この記事は下記の参考資料を元にした筆者の解釈の記述です。

正確さについては保証されませんので詳しくは下記の参考元をご参照ください。

APIとは

アプリケーションはシステムコールを使用してOSが提供するサービスを利用する。

ほとんどのシステムではシステムコールのラッパーとなるライブラリルーチンが提供されており、アプリケーションはこれを利用してシステムコールの呼び出しを実現している。

ライブラリルーチンを利用するとシステムコールをより簡単に扱うことができるようになる。

ライブラリルーチンやシステムコールを利用するための規約をAPIと呼び、これに従うことによってシステムコールを利用するアプリケーションを作成することが可能になる。

APIC言語で言うとそれが提供する関数の引数や戻り値、副作用などの処理内容について定められた仕様書のことである。

また、C言語のラッパーと考えることができるPHPなどの言語でも同様である。

このように言語が提供してくれているAPIがあることによってシステムコールやライブラリルーチンの仕様について無関心でもアプリケーションのプログラミングを行うことができる。

また、OSの違いによるシステムコールなどの仕様の違いをC言語などが吸収してくれる。

代表的なAPI

  • ANSI標準ライブラリ関数
    • いわゆる標準Cライブラリ
  • POSIX
  • OpenGL
    • 3DグラフィックプログラミングのためのAPI
  • ソケットAPI
    • TCP/IPによるネットワークプログラミングで使用される。