SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

pthreadについて

pthreadについて(概要・生成)

pthreadの概要、プロセスとの違い、生成方法


2. スレッドの生成と終了(1/2)

 スレッドは、pthread_createにより起動し、生成された新スレッドは引数にある関数を実行します。呼び出された関数はスレッド上で動き、その関数が終了すればスレッドも終了します。

 以下からはpthread_createの引数である関数をスレッドと呼びます。スレッドの生成や終了にかかわる関数を見ていきます。

2.1 リファレンス

 主にスレッドの生成にかかわる関数は下記の通りです。より詳細についてはmanコマンド、もしくはココを参照してください。

  • int pthread_create( pthread_t * id, pthread_attr_t * attr, void * (*routine)(void *), void * arg);
  • int pthread_join( pthread_t id, void ** thread_return );
  • int pthread_detach( pthread_t id );
  • void pthread_exit(void *retval );
  • pthread_t pthread_self( );

 pthread_create:新しいスレッドを生成します。

 pthread_t * id:スレッド識別子です。主にlongで実装されている事が多いです。スレッドの起動が成功するとpthread_createが値を設定します。以降、スレッドに対してアクセスする際に必要になります。スレッド内で自分自身のスレッド識別子を参照したい場合、pthread_self 関数によって取得可能です。

 pthread_attr_t * attr:スレッド属性用構造体です。スレッドを生成する時にだけ参照されます。 利用しない場合はNULLを設定する事でデフォルトの設定と同じになります(デフォルト設定:thread joinable, scheduling off, stack size default(私の環境では10M))。 pthread_attr_*関数により操作します。詳細については別章で説明します。

 start_routine:スレッドが起動する関数で、引数はstart_routineの後ろにあるvoid * argです。戻り値は親プロセスがpthread_joinの第2引数がNULLではない場合、そこに設定されます。

 pthread_join:スレッドの終了を待ちます。

 pthread_exitを呼び出して終了するか、取り消しされて終了するのを待ちます。

 thread_return:監視対象スレッドの戻り値の格納領域、NULLを設定する事で戻り値を精査しないことも可能。

 pthread_detach:スレッドをデタッチ状態へ移行させます。これによって親プロセスはpthread_joinで監視しなくてもよくなり、逆に監視するとエラーになります。

 pthread_exit:スレッドの終了、結果を返却します。通常は呼び出し先で使う事でスレッドを終了させます。retval にNULLではない値を入れると、その値はpthread_joinで参照できます。また、呼び出し元で使う事で、呼び出した全スレッドが終了するまで待つ事ができます。しかしプロセス自体はdefanct(つまりゾンビプロセス)扱いになります。なお、pthread_exit(retval) は、 return retval;と書く事もできます。

2.2 エラー対処

 従来のC/C++にて提供されている関数でエラーが発生すると、一般的には関数は戻り値として-1を返し、エラー種別として外部変数であるerrnoに値を設定します。しかしスレッドの場合は戻り値がエラー種別になります。正常値の時は0が帰ってきます。

 エラー情報を文字列で表示する strerror(3) には、errno ではなく戻り値をセットします。

2.3 サンプル

 以上の関数を使ったサンプルが下記です。

thread_sample.c
/* gcc thread_sample.c -o thread_sample -W -Wall -lpthread */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <ctype.h>

void * thread_function( void * arg );

int main( int argc, char ** argv ) {

    ( void )argc;
    pthread_t pt;
    char *    rtn_p = 0;
    char      buf[256];

    strcpy( buf, argv[0] );
    fprintf( stdout, "buf  :[%s]\n", buf );
    pthread_create( &pt, NULL, &thread_function, ( void * )buf );
    pthread_join( pt, ( void ** )&rtn_p );
/*  pthread_detach( pt ); */
    fprintf( stdout, "rtn_p:[%s]\n", rtn_p );
    return 0;
}

void * thread_function( void * arg ) {
    char * buf = malloc( strlen(( char * )arg ) + 1 );
    strcpy( buf, ( char * )arg );
    size_t i;
    for( i = 0; i < strlen( buf ); i ++ ) {
        buf[i] = toupper( buf[i] );
    }
    pthread_exit( buf );
}

次のページ
2. スレッドの生成と終了(2/2):起動可能なスレッド数

この記事は参考になりましたか?

pthreadについて連載記事一覧

もっと読む

この記事の著者

赤松 エイト(エイト)

(株)DTSに勤てます。WebアプリやJavaやLL等の上位アプリ環境を密かに憧れつつも、ず~っとLinuxとかHP-UXばかり、ここ数年はカーネル以上アプリ未満のあたりを行ったり来たりしています。mixiもやってまして、こちらは子育てとか日々の日記メインです。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/1892 2008/08/20 15:58

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー