UNIX

目次

表記上の規則

この文書では、次のような字体や記号を特別な意味を持つものとして使用します。

表記上の規則
字体または記号意味
AaBbCc123コマンド名、ファイル名、およびディレクトリ名を示します。または、画面上のコンピュータ出力を示します。
AaBbCc123ユーザーが入力する文字を、画面上のコンピュータ出力と区別して示します。
AaBbCc123変数を示します。実際に使用する特定の名前または値で置き換えます。

コード例は次のように表示されます。

system% command [filename]

[ ] は省略可能な項目を示します。上記の場合、filename は省略してもよいことを示します。

UNIXの概要

UNIXは1969年、AT&T社のベル研究所でKen ThompsonとDennis Ritchieの2人によって開発されました。

UNIXの標準化を巡って、かつては Unix International (UI) と Open Software Foundation (OSF) という2つの陣営に分かれたことがありました。

Unix International (UI) は、AT&T 社を中心とするグループで、Open Software Foundation (OSF) は、IBM社を中心とするグループでした。どちらも、UNIXの標準化を図るために設立された業界団体です。

X/Openは、UNIXの標準化を図るために設立された業界団体です。OSFと合併してThe Open Groupとなりました。

「UNIX」という商標の権利は、かつてAT&Tが所有していましたが、X/Openを経て、The Open Groupに所有権が移りました。

端末エミュレータ−

端末エミュレータ−とは、かつて UNIX の端末として使われていたダム端末のエミュレーション(模擬動作)をするソフトウェアです。 ダム端末とはキーボードから文字を入力したり文字をディスプレイに表示するといった基本的な機能のみを持つ端末です。 現在では PC のように高度な機能を持つ端末もありますが、かつてはダム端末が UNIX の端末として用いられてきました。

端末の入出力の方法には統一された規格がありませんが、事実上の標準として用いられているのが DEC社の VT100 端末です。 端末エミュレータ−では環境変数などの設定により、VT100 を初め様々な端末のエミュレーションを行えます。

エラー番号

システムコールを呼び出した際にエラーが発生すると、外部変数 errno にエラー番号が格納されます。

エラー番号
番号名前意味
1EPERMスーパーユーザーではありません。
2ENOENTファイルまたはディレクトリが存在しません。
3ESRCHプロセス、LWP、またはスレッドが存在しません。
4EINTRシステムコールに割り込みが発生しました。
22EINVAL不正な引数です。
28ENOSPCデバイスに空き領域がありません。

write(2)システムコールは、直接ディスクに書き込むわけではありません。書き込みをスケジュールするだけです。ディスクの空き領域が足りない場合でも、ENOSPCでエラーになるとは限りません。書き込みに成功したかどうかは、fsync(2)を呼び出したうえ、close(2)の戻り値を確認する必要があります。

System V のIPC

システムVのIPC (inter-process communication) には、次の3種類があります。

ipcs

アクティブなIPCファシリティに関する情報を表示するには、ipcsコマンドを使用します。

ipcs [ -a ]

出力結果は、以下のフィールドに分かれています。

T
ファシリティのタイプ
T意味
qメッセージ・キュー
m共有メモリー・セグメント
sセマフォ
ID
ファシリティ・エントリーの識別子
KEY
ファシリティ・エントリーのキー
MODE
ファシリティのアクセス・モードとフラグ
OWNER
ファシリティ・エントリー所有者のログイン名
GROUP
ファシリティ・エントリー所有者のグループ名

ソケット

ソケットはプロセス間通信 (Inter Process Communication: IPC) の一種で、ネットワークで接続された異なる計算機上のプロセスと通信できることが特徴です。ソケットはストリーム型データグラム型の2種類に分けられます。

ストリームソケット (コネクション型、TCP/IP)

SOCK_STREAM型を指定したソケットを利用する、ストリーム指向のクライアント/サーバー通信は、データグラム指向の通信よりもやや複雑です。複雑ではありますが、信頼性の高い通信経路を提供します。

SOCK_STREAM型ソケットを使用した、クライアント/サーバー処理の流れを次に示します。

SOCK_STREAM

socket()関数は、ソケット(socket)と呼ばれる通信の端点を作り出します。

bind()でソケットに名称を付与します。

listen()でクライアントからの接続要求を受け付けます。

accept()でクライアントからの接続要求を待ち合わせます。接続要求を受信すると、新規ソケットを生成します。

connect()でサーバーに接続します。

指定ホストと通信可能で、指定ポート番号のソケットが開いていない場合、connect()ECONNREFUSED でエラー終了します。

ホストと通信できない場合、一定の時間経過後にconnect()はETIMEOUTでエラー終了します。Solarisの場合、タイムアウト時間はnddコマンドで確認することができます。

$ ndd /dev/tcp tcp_ip_abort_cinterval
180000

値はミリ秒単位です。

send()またはwrite()でデータの送信、recv()またはread()でデータを受信します。

close()で接続を切断します。

データグラムソケット (コネクションレス型、UDP/IP)

SOCK_DGRAM型のソケットを使ったデータグラム指向のクライアント/サーバー通信は、ストリーム指向の通信より単純です。簡単ではありますが、信頼性は低いです。

サーバーは、クライアントからの接続を受容(accept)するために聴取(listen)を行う必要はなく、クライアントはサーバーに接続(connect)する必要がありません。

SOCK_DGRAM型ソケットを使用した、クライアント/サーバー処理の流れを次に示します。

SOCK_DGRAM

socket()

int socket(int domain, int type, int protocol);
PF_UNIX
UNIX system internal protocols
PF_INET
Internet Protocol Version 4 (IPv4)
PF_INET6
Internet Protocol Version 6 (IPv6)
PF_NCA
Network Cache and Accelerator (NCA) protocols
SOCK_STREAM
ストリーム指向 (TCP/IP)
SOCK_DGRAM
データグラム指向 (UDP/IP)

共有ライブラリの動的ロード

共有ライブラリの動的ロードとは、共有ライブラリ内に含まれている関数を実際に利用する時点になって、初めて共有ライブラリをメモリにロードする方法です。

共有ライブラリを動的にロードするには、dlopen関数を使用します。

void *dlopen(const char *pathname, int mode);

引数pathnameには、ロードする共有ライブラリのパス名を指定します。絶対パス名と相対パス名のどちらで指定しても構いません。パス名ではなく、ファイル名だけを指定することもできます。ファイル名だけを指定した場合、環境変数 LD_LIBRARY_PATH に設定されたディレクトリ群から指定された共有ライブラリを探します。

引数modeにはモードを表す識別子を指定します。

dlopenは、成功するとハンドルへのポインタを返します。失敗するとNULLを返します。

動的にロードしたライブラリに含まれる関数へのポインタを取得するには、dlsym関数を使用します。

void *dlsym(void *handle, const char *name);

引数handleには、ハンドルへのポインタ(dlopenの戻り値)を指定します。

引数nameには、関数の名前を格納したバッファへのポインタを指定します。

dlsymは、成功すると関数へのポインタを返します。失敗するとNULLを返します。

ハンドルをクローズするには、dlclose関数を使用します。ハンドルをクローズすると、参照カウンタが減らされます。参照カウンタが0になると、ライブラリがアンロードされます。

int dlclose(void *handle);

動的ロード関数が失敗したときは、dlerror関数を使用することにより、エラー・メッセージを取得することができます。

char *dlerror(void);

dlerrorは、成功するとエラー・メッセージ文字列が格納されたバッファへのポインタを返します。エラーが発生していない場合は、NULLを返します。

共有ライブラリを動的にロードするサンプル・ソースコードを次に示します。

void *handle;
int (*func)(int);

handle = dlopen("libsample.so", RTLD_LAZY);
if (handle != NULL) {
    func = (int (*)(int))dlsym(handle, "sample_function");
    if (func != NULL) {
        (*func)(0);
    } else {
        fprintf(stderr, "%s\n", dlerror());
    }
    dlclose(handle);
} else {
    fprintf(stderr, "%s\n", dlerror());
}

POSIXスレッド (pthread)

POSIXスレッド (pthread) とは

POSIXスレッド (pthread) は、POSIX (Portable Operating System Interface) によって定められたスレッド・インタフェースです。

UNIXにおいてマルチスレッドを扱う場合、各UNIX固有の方法より、POSIXスレッドの方が移植性が高くなります。

POSIXスレッド (pthread) プログラミング

スレッドの終了

スレッドの終了には、下記の方法があります。

pthread関数リファレンス

pthread_create

現在のプロセスに新しい制御スレッドを追加します。

構文
int pthread_create(pthread_t *tid, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
引数
pthread_create関数の引数
引数入出力説明
tidpthread_t *出力生成されたスレッドの識別子を格納する領域へのポインタ
attrpthread_attr_t *入力スレッドの属性
start_routinevoid *入力新しいスレッドを実行する関数へのポインタ

引数attrにはスレッドの属性を指定します。属性を初期化するには、pthread_attr_init関数を使用します。NULLを指定すると、デフォルトの属性が適用されます。

戻り値

正常終了時は0です。それ以外の戻り値は、エラーが発生したことを示します。

pthread_join

スレッドの終了を待ちます。切り離していないスレッドのみ有効です。

構文
int pthread_join(pthread_t tid, void **status);
引数
pthread_join関数の引数
引数入出力説明
tidpthread_t入力スレッドの識別子
statusvoid **出力スレッドの終了状態を格納する領域へのポインタ。終了状態を取得する必要が無いときは、NULLを指定します。
戻り値

正常終了時は0です。それ以外の戻り値は、エラーが発生したことを示します。

pthread_detach

スレッドを切り離します。

構文
int pthread_detach(pthread_t tid);
引数
pthread_detach関数の引数
引数入出力説明
tidpthread_t入力スレッドの識別子
戻り値

正常終了時は0です。それ以外の戻り値は、エラーが発生したことを示します。

pthread_exit

スレッドを終了させます。

構文
void pthread_exit(void *status);
引数
pthread_exit関数の引数
引数入出力説明
statusvoid *入力スレッドの終了状態を格納した領域へのポインタ。終了状態を戻す必要が無いときはNULLを指定します。

pthread_cancel

スレッドを取り消します。

構文
int pthread_cancel(pthread_t tid);
引数
pthread_cancel関数の引数
引数入出力説明
tidpthread_t入力スレッドの識別子
戻り値

正常終了時は0です。それ以外の戻り値は、エラーが発生したことを示します。

SEO 仕事 掲示板 レンタルサーバー プロフ SEO