てきとうなさいと べぇたばん

PHPのソースを覗いてみるメモ スレッド

PHPのソースをなんとなく覗く

sapi/cli/php_cli.cをなんとなく覗いてた。

TSRMというなんだか変な名前があるのだが、これはスレッドセーフなリソースマネージャのことを指す。

tsrm_startup

sapi/cli/php_cli.cの1259行目。main関数の中にある、tsrm_startup関数が呼ばれる。これがスレッドセーフなリソースマネージャを初期化するための関数かしら。

--with-tsrm-pthreads    Use POSIX threads (default)

pthread_key_create

TSD(thread-specific data:スレッド固有データ)キーを確保する。

94行目

static pthread_key_t tls_key;

tsrm_mutex_alloc

Allocate a mutexとある。mutex(ミューテックス)とは、Wikipediaを覗くとこんなことが書いてある。

クリティカルセクションでアトミック性を確保するための同期機構の一種である。Mutexという語はMUTual EXclusion(相互排他)の省略形となっている。

…わけわからなかった。「Windowsはなぜ動くのか」だったらなにか書いてあるかもしれない。

262ページに書いてあった。

「ミューテックス(MUTEX)」とは、相互排他を意味する「mutual exclusion」から作られた造語で、その名前が示すように複数のプロセスで排他制御を行うのに最も有効な方法です。

ミューテックス・オブジェクトの貸し出しや返却といった作業は、すべてWindowsのシステム・コールによって行います。システム・コールの内部では、先に述べたような不意のタスク切り替えなどが発生しませんから、うっかり複数のプロセスがミューテックス・オブジェクトの貸出を受けてしまうことはもちろん発生しません。

ミューテックス・オブジェクトを作成する

POSIX threadsを元にするので、pthread_mutex_initを呼び出すことになる。

スレッド固有データの読み取り

一番最初にts_resourceが呼び出され、呼び出しスレッド0に結び付けられている値を呼び出す。 具体的な処理としては、pthread_getspecific

POSIX スレッドを試してみる

http://www.ibm.com/developerworks/jp/linux/library/l-posix1/

ソース

#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

void *thread_function(void *arg) {
    int i;
    for (i = 0; i < 20; i++) {
        printf("Thread says hi!\\n");
        sleep(1);
    }
    return NULL;
}

void *echo_function(void *arg) {
    int i;
    for (i = 0; i < 20; i++) {
        printf("Thread says echo!\\n");
        sleep(1);
    }
    return NULL;
}

int main(void) {
    pthread_t mythread;
    pthread_t myecho;

    // pthread_create 実際のスレッドを作成する。
    // プログラムは2つのスレッドから構成される。(このプログラムと作成したスレッド)
    if (pthread_create(&mythread, NULL, thread_function, NULL)) {
        printf("error creating thread.");
        abort();
    }

    if (pthread_create(&myecho, NULL, echo_function, NULL)) {
        printf("error creating thread.");
        abort();
    }

    // 2つのスレッドを1つのスレッドにマージする
    // この例では、thread_functionが終了する前にここにたどり着くのでマージできない。
    // できるように(thread_functionが終了するまで)待つ。
    if (pthread_join(mythread, NULL)) {
        printf("error joining thread.");
        abort();
    }

    if (pthread_join(myecho, NULL)) {
        printf("error joining thread.");
        abort();
    }

    // で、1つのスレッドに戻る
    exit(0);
}

これをコンパイルして実行してみると、Thread says echo!Thread says hi!がそれぞれのスレッドで1秒毎に表示される。そのため、以下のようになる。たぶん。

$ ./thread_ex
Thread says echo!
Thread says hi!
Thread says echo!
Thread says hi!
Thread says echo!
Thread says hi!
Thread says echo!
Thread says hi!
Thread says echo!
Thread says hi!
Thread says echo!
Thread says hi!
Thread says echo!
Thread says hi!
Thread says echo!
Thread says hi!
Thread says echo!
Thread says hi!
Thread says echo!
Thread says hi!
Thread says echo!
Thread says hi!
Thread says echo!
Thread says hi!
Thread says echo!
Thread says hi!
Thread says echo!
Thread says hi!
Thread says echo!
Thread says hi!
Thread says echo!
Thread says hi!
Thread says echo!
Thread says hi!
Thread says echo!
Thread says hi!
Thread says echo!
Thread says hi!
Thread says echo!
Thread says hi!
threadの作成
18712 pts/3    -      0:00 ./thread1
    - -        Sl+    0:00 -
    - -        Sl+    0:00 -