リスト


〔リスト1〕プロセスの実行(test200.c)
/*
 *プロセスの実行
 */
#include <sys/types.h>
#include <unistd.h>
int main(void)
{
     pid_t child_pid;
     child_pid = fork();
     execl("/usr/bin/xine","xine");
     system("ps -Al > test.log");
}


〔リスト2〕スレッドの生成と実行test200.log)
/*
 *スレッドの生成と実行
 */
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

void *thread_function1(void *arg) 
{
    int i;
    printf("スレッド1のスレッドID=%d\n",pthread_self());
    sleep(1);
    for ( i=0; i<3; i++ ) 
    {
        printf("スレッド1を実行中\n");
        sleep(1);
    }
    return NULL;
}
void *thread_function2(void *arg) 
{
    int i;
    printf("スレッド2のスレッドID=%d\n",pthread_self());
    sleep(1);
    for ( i=0; i<3; i++ ) 
    {
        printf("スレッド2を実行中\n");
        sleep(1);
    }
    return NULL;
}

int main(void) 
{
    pthread_t thread1;
    pthread_t thread2;
    printf("メインスレッドのスレッドID=%d\n",pthread_self());
    sleep(1);
    if ( pthread_create( &thread1, NULL, thread_function1,NULL))
    {
        printf("スレッド1生成に失敗\n");
        abort();
    }
    if ( pthread_create( &thread2, NULL, thread_function2,NULL))
    {
        printf("スレッド2生成に失敗\n");
        abort();
    }
    if ( pthread_join ( thread1, NULL ) ) 
    {
        printf("スレッド1と合流に失敗\n");
        abort();
    }
    if ( pthread_join ( thread2, NULL ) ) 
    {
        printf("スレッド2と合流に失敗\n");
        abort();
    }
    exit(0);
}

〔リスト3〕単純な関数処理のソースtest201a.c)
/*
 *単純な関数
 */
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

void *thread_function1() 
{
    int i;
    for ( i=0; i<3; i++ ) 
    {
        printf("関数1を実行中\n");
        sleep(1);
    }
    return NULL;
}
void *thread_function2() 
{
    int i;
    for ( i=0; i<3; i++ ) 
    {
        printf("関数2を実行中\n");
        sleep(1);
    }
    return NULL;
}

int main(void) 
{
    char    *thread1;
    char    *thread2;
    thread1 =   thread_function1();
    thread1 =   thread_function2();
    exit(0);
}

〔リスト4〕スレッド処理(test201.s
    .file   "test201.c"
    .section    .rodata
.LC0:
    .string "\245\271\245\354\245\303\245\311\243\261\244\316
   \245\271\245\354\245\303\245\311\243\311\243\304\241\341%d\n"
.LC1:
    .string "\245\271\245\354\245\303\245\311\243\261\244\362
                                     \274\302\271\324\303\346\n"
    .text
.globl thread_function1
    .type   thread_function1, @function
thread_function1:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $24, %esp
    call    pthread_self
    movl    %eax, 4(%esp)
    movl    $.LC0, (%esp)
    call    printf
    movl    $1, (%esp)
    call    sleep
    movl    $0, -4(%ebp)
.L2:
    cmpl    $2, -4(%ebp)
    jle .L5
    jmp .L3
.L5:
    movl    $.LC1, (%esp)
    call    printf
    movl    $1, (%esp)
    call    sleep
    leal    -4(%ebp), %eax
    incl    (%eax)
    jmp .L2
.L3:
    movl    $0, %eax
    leave
    ret
    .size   thread_function1, .-thread_function1
    .section    .rodata
.LC2:
    .string "\245\271\245\354\245\303\245\311\243\262\244\316
   \245\271\245\354\245\303\245\311\243\311\243\304\241\341%d\n"
.LC3:
    .string "\245\271\245\354\245\303\245\311\243\262\244\362
                                     \274\302\271\324\303\346\n"
    .text
.globl thread_function2
    .type   thread_function2, @function
thread_function2:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $24, %esp
    call    pthread_self
    movl    %eax, 4(%esp)
    movl    $.LC2, (%esp)
    call    printf
    movl    $1, (%esp)
    call    sleep
    movl    $0, -4(%ebp)
.L7:
    cmpl    $2, -4(%ebp)
    jle .L10
    jmp .L8
.L10:
    movl    $.LC3, (%esp)
    call    printf
    movl    $1, (%esp)
    call    sleep
    leal    -4(%ebp), %eax
    incl    (%eax)
    jmp .L7
.L8:
    movl    $0, %eax
    leave
    ret
    .size   thread_function2, .-thread_function2
    .section    .rodata
    .align 32
.LC4:
    .string "\245\341\245\244\245\363\245\271\245\354\245\303
   \245\311\244\316\245\271\245\354\245\303\245\311\243\311\243
                                               \304\241\341%d\n"
.LC5:
    .string "\245\271\245\354\245\303\245\3111\300\270\300\256
                                     \244\313\274\272\307\324\n"
.LC6:
    .string "\245\271\245\354\245\303\245\3112\300\270\300\256
                                     \244\313\274\272\307\324\n"
.LC7:
    .string "\245\271\245\354\245\303\245\3111\244\310\271\347
                             \316\256\244\313\274\272\307\324\n"
.LC8:
    .string "\245\271\245\354\245\303\245\3112\244\310\271\347
                             \316\256\244\313\274\272\307\324\n"
    .text
.globl main
    .type   main, @function
main:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $24, %esp
    andl    $-16, %esp
    movl    $0, %eax
    subl    %eax, %esp
    call    pthread_self
    movl    %eax, 4(%esp)
    movl    $.LC4, (%esp)
    call    printf
    movl    $1, (%esp)
    call    sleep
    movl    $0, 12(%esp)
    movl    $thread_function1, 8(%esp)
    movl    $0, 4(%esp)
    leal    -4(%ebp), %eax
    movl    %eax, (%esp)
    call    pthread_create
    testl   %eax, %eax
    je  .L12
    movl    $.LC5, (%esp)
    call    printf
    call    abort
.L12:
    movl    $0, 12(%esp)
    movl    $thread_function2, 8(%esp)
    movl    $0, 4(%esp)
    leal    -8(%ebp), %eax
    movl    %eax, (%esp)
    call    pthread_create
    testl   %eax, %eax
    je  .L13
    movl    $.LC6, (%esp)
    call    printf
    call    abort
.L13:
    movl    $0, 4(%esp)
    movl    -4(%ebp), %eax
    movl    %eax, (%esp)
    call    pthread_join
    testl   %eax, %eax
    je  .L14
    movl    $.LC7, (%esp)
    call    printf
    call    abort
.L14:
    movl    $0, 4(%esp)
    movl    -8(%ebp), %eax
    movl    %eax, (%esp)
    call    pthread_join
    testl   %eax, %eax
    je  .L15
    movl    $.LC8, (%esp)
    call    printf
    call    abort
.L15:
    movl    $0, (%esp)
    call    exit
    .size   main, .-main
    .ident  "GCC: (GNU) 3.3"


〔リスト5〕関数処理test201a.s)
    .file   "test201a.c"
    .section    .rodata
.LC0:
    .string "\264\330\277\364\243\261\244\362\274\302\271\324
                                                     \303\346\n"
    .text
.globl thread_function1
    .type   thread_function1, @function
thread_function1:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $8, %esp
    movl    $0, -4(%ebp)
.L2:
    cmpl    $2, -4(%ebp)
    jle .L5
    jmp .L3
.L5:
    movl    $.LC0, (%esp)
    call    printf
    movl    $1, (%esp)
    call    sleep
    leal    -4(%ebp), %eax
    incl    (%eax)
    jmp .L2
.L3:
    movl    $0, %eax
    leave
    ret
    .size   thread_function1, .-thread_function1
    .section    .rodata
.LC1:
    .string "\264\330\277\364\243\262\244\362\274\302\271\324
                                                     \303\346\n"
    .text
.globl thread_function2
    .type   thread_function2, @function
thread_function2:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $8, %esp
    movl    $0, -4(%ebp)
.L7:
    cmpl    $2, -4(%ebp)
    jle .L10
    jmp .L8
.L10:
    movl    $.LC1, (%esp)
    call    printf
    movl    $1, (%esp)
    call    sleep
    leal    -4(%ebp), %eax
    incl    (%eax)
    jmp .L7
.L8:
    movl    $0, %eax
    leave
    ret
    .size   thread_function2, .-thread_function2
.globl main
    .type   main, @function
main:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $24, %esp
    andl    $-16, %esp
    movl    $0, %eax
    subl    %eax, %esp
    call    thread_function1
    movl    %eax, -4(%ebp)
    call    thread_function2
    movl    %eax, -4(%ebp)
    movl    $0, (%esp)
    call    exit
    .size   main, .-main
    .ident  "GCC: (GNU) 3.3"

〔リスト6〕共有のメモリ空間を使用するtest202.c)
/*
 *共有のメモリ空間を使用する
 *優先度:スレッド1→スレッド2
 */
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sched.h>

int Gint;
void *thread_function1(void *arg) 
{
    int i;
    int x;
    printf("スレッド1のスレッドID=%d\n",pthread_self());
    for ( x=0; x<10000000; x++ ) 
    {
    }
    Gint    =   1000;
    printf("スレッド1を開始します Gintの初期値は=\n%d\n",Gint);
    for ( x=0; x<10000; x++ ) 
    {
        Gint++;
        for ( i=0; i<2000; i++ ) 
        {
        }
    }
    printf("スレッド1が終了しました Gintの値は=\n%d\n",Gint);
    return NULL;
}
void *thread_function2(void *arg) 
{
    int i;
    int x;
    printf("スレッド2のスレッドID=%d\n",pthread_self());
    for ( x=0; x<10000000; x++ ) 
    {
    }
    Gint    =   2000;
    printf("スレッド2を開始します Gintの初期値は=\n%d\n",Gint);
    for ( x=0; x<10000; x++ ) 
    {
        Gint++;
        for ( i=0; i<2000; i++ ) 
        {
        }
    }
    printf("スレッド2が終了しました Gintの値は=\n%d\n",Gint);
    return NULL;
}

int main(void) 
{
    int i;
    pthread_attr_t  thread1_attr;
    pthread_attr_t  thread2_attr;
    struct  sched_param thread1_param;
    struct  sched_param thread2_param;
    pthread_t thread1;
    pthread_t thread2;
    printf("メインスレッドのスレッドID=%d\n",pthread_self());
    pthread_attr_init (&thread1_attr);
    pthread_attr_getschedparam (&thread1_attr, &thread1_param);
    thread1_param.sched_priority =  10000;
    pthread_attr_setschedparam (&thread1_attr, &thread1_param);
    if ( pthread_create( &thread1, &thread1_attr,
                                      thread_function1, NULL) )
    {
        printf("スレッド1生成に失敗\n");
        abort();
    }
    pthread_attr_init (&thread2_attr);
    pthread_attr_getschedparam (&thread2_attr, &thread2_param);
    thread2_param.sched_priority =  0;
    pthread_attr_setschedparam (&thread2_attr, &thread2_param);
    if ( pthread_create( &thread2, &thread2_attr, 
                                      thread_function2, NULL) )
    {
        printf("スレッド2生成に失敗\n");
        abort();
    }
    if ( pthread_join ( thread1, NULL ) )
    {
        printf("スレッド1と合流に失敗\n");
        abort();
    }
    {
        printf("スレッド2生成に失敗\n");
        abort();
    }
    if ( pthread_join ( thread2, NULL ) )
    {
        printf("スレッド2と合流に失敗\n");
        abort();
    }

    exit(0);

}

〔リスト7〕共有のメモリ空間を使用するtest203.c)
/*
 *共有のメモリ空間を使用する
 *優先度:スレッド2→スレッド1
 */
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sched.h>

int Gint;
void *thread_function1(void *arg) 
{
    int i;
    int x;
    printf("スレッド1のスレッドID=%d\n",pthread_self());
    for ( x=0; x<10000000; x++ ) 
    {
    }
    Gint    =   1000;
    printf("スレッド1を開始します Gintの初期値は=\n%d\n",Gint);
    for ( x=0; x<10000; x++ ) 
    {
        Gint++;
        for ( i=0; i<2000; i++ ) 
        {
        }
    }
    printf("スレッド1が終了しました Gintの値は=\n%d\n",Gint);
    return NULL;
}
void *thread_function2(void *arg) 
{
    int i;
    int x;
    printf("スレッド2のスレッドID=%d\n",pthread_self());
    for ( x=0; x<10000000; x++ ) 
    {
    }
    Gint    =   2000;
    printf("スレッド2を開始します Gintの初期値は=\n%d\n",Gint);
    for ( x=0; x<10000; x++ ) 
    {
        Gint++;
        for ( i=0; i<2000; i++ ) 
        {
        }
    }
    printf("スレッド2が終了しました Gintの値は=\n%d\n",Gint);
    return NULL;
}

int main(void) 
{
    int i;
    pthread_attr_t  thread1_attr;
    pthread_attr_t  thread2_attr;
    struct  sched_param thread1_param;
    struct  sched_param thread2_param;
    pthread_t thread1;
    pthread_t thread2;
    printf("メインスレッドのスレッドID=%d\n",pthread_self());
    pthread_attr_init (&thread1_attr);
    pthread_attr_getschedparam (&thread1_attr, &thread1_param);
    thread1_param.sched_priority =  0;
    pthread_attr_setschedparam (&thread1_attr, &thread1_param);
    if ( pthread_create( &thread1, &thread1_attr,
                                      thread_function1, NULL) )
    {
        printf("スレッド1生成に失敗\n");
        abort();
    }
    pthread_attr_init (&thread2_attr);
    pthread_attr_getschedparam (&thread2_attr, &thread2_param);
    thread2_param.sched_priority =  10000;
    pthread_attr_setschedparam (&thread2_attr, &thread2_param);
    if ( pthread_create( &thread2, &thread2_attr,
                                      thread_function2, NULL) )
    {
        printf("スレッド2生成に失敗\n");
        abort();
    }
    if ( pthread_join ( thread1, NULL ) ) 
    {
        printf("スレッド1と合流に失敗\n");
        abort();
    }
    if ( pthread_join ( thread2, NULL ) ) 
    {
        printf("スレッド2と合流に失敗\n");
        abort();
    }

    exit(0);

}

〔リスト8〕mutexを使用して変数をロックするtest204.c)
/*
 *共有のメモリ空間を使用する
 *mutex使用
 */
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sched.h>
pthread_mutex_t test_mutex=PTHREAD_MUTEX_INITIALIZER;

int Gint;
void *thread_function1(void *arg) 
{
    int i;
    int x;
    pthread_mutex_lock(&test_mutex);
    printf("スレッド1のスレッドID=%d\n",pthread_self());
    for ( x=0; x<10000000; x++ ) 
    {
    }
    Gint    =   1000;
    printf("スレッド1を開始します Gintの初期値は=\n%d\n",Gint);
    for ( x=0; x<10000; x++ ) 
    {
        Gint++;
        for ( i=0; i<2000; i++ ) 
        {
        }
    }
    printf("スレッド1が終了しました Gintの値は=\n%d\n",Gint);
    pthread_mutex_unlock(&test_mutex);
    return NULL;
}
void *thread_function2(void *arg) 
{
    int i;
    int x;
    pthread_mutex_lock(&test_mutex);
    printf("スレッド2のスレッドID=%d\n",pthread_self());
    for ( x=0; x<10000000; x++ ) 
    {
    }
    Gint    =   2000;
    printf("スレッド2を開始します Gintの初期値は=\n%d\n",Gint);
    for ( x=0; x<10000; x++ ) 
    {
        Gint++;
        for ( i=0; i<2000; i++ ) 
        {
        }
    }
    printf("スレッド2が終了しました Gintの値は=\n%d\n",Gint);
    pthread_mutex_unlock(&test_mutex);
    return NULL;
}

int main(void) 
{
    int i;
    pthread_attr_t  thread1_attr;
    pthread_attr_t  thread2_attr;
    struct  sched_param thread1_param;
    struct  sched_param thread2_param;
    pthread_t thread1;
    pthread_t thread2;
    printf("メインスレッドのスレッドID=%d\n",pthread_self());
    pthread_attr_init (&thread1_attr);
    pthread_attr_getschedparam (&thread1_attr, &thread1_param);
    thread1_param.sched_priority =  0;
    pthread_attr_setschedparam (&thread1_attr, &thread1_param);
    if ( pthread_create( &thread1, &thread1_attr,
                                      thread_function1, NULL) )
    {
        printf("スレッド1生成に失敗\n");
        abort();
    }
    pthread_attr_init (&thread2_attr);
    pthread_attr_getschedparam (&thread2_attr, &thread2_param);
    thread2_param.sched_priority =  10000;
    pthread_attr_setschedparam (&thread2_attr, &thread2_param);
    if ( pthread_create( &thread2, &thread2_attr,
                                      thread_function2, NULL) )
    {
        printf("スレッド2生成に失敗\n");
        abort();
    }
    if ( pthread_join ( thread1, NULL ) ) 
    {
        printf("スレッド1と合流に失敗\n");
        abort();
    }
    if ( pthread_join ( thread2, NULL ) ) 
    {
        printf("スレッド2と合流に失敗\n");
        abort();
    }

    exit(0);

〔リスト9〕スレッド実行権限の譲渡test205.c)
/*
 *共有のメモリ空間を使用する
 *スレッド実行権限の譲渡
 */
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sched.h>
pthread_mutex_t test_mutex=PTHREAD_MUTEX_INITIALIZER;

int Gint;
void *thread_function1(void *arg) 
{
    int i;
    int x;
    sched_yield();
    printf("スレッド1のスレッドID=%d\n",pthread_self());
    for ( x=0; x<10000000; x++ ) 
    {
        sched_yield();
    }
    Gint    =   1000;
    printf("スレッド1を開始します Gintの初期値は=\n%d\n",Gint);
    for ( x=0; x<10000; x++ ) 
    {
        Gint++;
        for ( i=0; i<2000; i++ ) 
        {
        }
    }
    printf("スレッド1が終了しました Gintの値は=\n%d\n",Gint);
    return NULL;
}
void *thread_function2(void *arg) 
{
    int i;
    int x;
    printf("スレッド2のスレッドID=%d\n",pthread_self());
    for ( x=0; x<10000000; x++ ) 
    {
    }
    Gint    =   2000;
    printf("スレッド2を開始します Gintの初期値は=\n%d\n",Gint);
    for ( x=0; x<10000; x++ ) 
    {
        Gint++;
        for ( i=0; i<2000; i++ ) 
        {
        }
    }
    printf("スレッド2が終了しました Gintの値は=\n%d\n",Gint);
    sched_yield();
    return NULL;
}

int main(void) 
{
    int i;
    pthread_attr_t  thread1_attr;
    pthread_attr_t  thread2_attr;
    struct  sched_param thread1_param;
    struct  sched_param thread2_param;
    pthread_t thread1;
    pthread_t thread2;
    printf("メインスレッドのスレッドID=%d\n",pthread_self());
    pthread_attr_init (&thread1_attr);
    pthread_attr_getschedparam (&thread1_attr, &thread1_param);
    thread1_param.sched_priority =  1000;
    pthread_attr_setschedparam (&thread1_attr, &thread1_param);
    if ( pthread_create( &thread1, &thread1_attr,
                                      thread_function1, NULL) )
    {
        printf("スレッド1生成に失敗\n");
        abort();
    }
    pthread_attr_init (&thread2_attr);
    pthread_attr_getschedparam (&thread2_attr, &thread2_param);
    thread2_param.sched_priority =  1000;
    pthread_attr_setschedparam (&thread2_attr, &thread2_param);
    if ( pthread_create( &thread2, &thread2_attr,
                                      thread_function2, NULL) )
    {
        printf("スレッド2生成に失敗\n");
        abort();
    }
    if ( pthread_join ( thread1, NULL ) ) 
    {
        printf("スレッド1と合流に失敗\n");
        abort();
    }
    if ( pthread_join ( thread2, NULL ) ) 
    {
        printf("スレッド2と合流に失敗\n");
        abort();
    }

    exit(0);

〔リスト10〕セマフォを使ったスレッド管理test206.c)
/*
 *共有のメモリ空間を使用する
 *セマフォを使ったスレッド管理
 */
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sched.h>
#include <semaphore.h>


int Gint;
sem_t sem;
int count;
void *thread_function1(void *arg) 
{
    int i;
    int x;
    int ret;
//セマフォの値がゼロ以上になるまでスレッドを停止
    ret = sem_wait(&sem); 
    printf("スレッド1のスレッドID=%d\n",pthread_self());
    for ( x=0; x<10000000; x++ ) 
    {
    }
    Gint    =   1000;
    printf("スレッド1を開始します Gintの初期値は=\n%d\n",Gint);
    for ( x=0; x<10000; x++ ) 
    {
        Gint++;
        for ( i=0; i<2000; i++ ) 
        {
        }
    }
    printf("スレッド1が終了しました Gintの値は=\n%d\n",Gint);
    return NULL;
}
void *thread_function2(void *arg) 
{
    int i;
    int x;
    int ret;
    printf("スレッド2のスレッドID=%d\n",pthread_self());
    for ( x=0; x<10000000; x++ ) 
    {
    }
    Gint    =   2000;
    printf("スレッド2を開始します Gintの初期値は=\n%d\n",Gint);
    for ( x=0; x<10000; x++ ) 
    {
        Gint++;
        for ( i=0; i<2000; i++ ) 
        {
        }
    }
    printf("スレッド2が終了しました Gintの値は=\n%d\n",Gint);
//セマフォの値に1を加算
    ret = sem_post(&sem);
    return NULL;
}

int main(void) 
{
    int i;
    int ret;
    pthread_attr_t  thread1_attr;
    pthread_attr_t  thread2_attr;
    struct  sched_param thread1_param;
    struct  sched_param thread2_param;
    pthread_t thread1;
    pthread_t thread2;
//このプロセスだけで使用できるセマフォ
    count   =   0;
    ret = sem_init(&sem, 0, count); 
//
    printf("メインスレッドのスレッドID=%d\n",pthread_self());
    pthread_attr_init (&thread1_attr);
    pthread_attr_getschedparam (&thread1_attr, &thread1_param);
    thread1_param.sched_priority =  1000;
    pthread_attr_setschedparam (&thread1_attr, &thread1_param);
    if ( pthread_create( &thread1, &thread1_attr,
                                      thread_function1, NULL) )
    {
        printf("スレッド1生成に失敗\n");
        abort();
    }
    pthread_attr_init (&thread2_attr);
    pthread_attr_getschedparam (&thread2_attr, &thread2_param);
    thread2_param.sched_priority =  1000;
    pthread_attr_setschedparam (&thread2_attr, &thread2_param);
    if ( pthread_create( &thread2, &thread2_attr,
                                      thread_function2, NULL) )
    {
        printf("スレッド2生成に失敗\n");
        abort();
    }
    if ( pthread_join ( thread1, NULL ) ) 
    {
        printf("スレッド1と合流に失敗\n");
        abort();
    }
    if ( pthread_join ( thread2, NULL ) ) 
    {
        printf("スレッド2と合流に失敗\n");
        abort();
    }

    exit(0);

}
NEW記事内インデックス    連載インデックスはこちら   Interfaceのトップ
GCCにおけるマルチスレッドへの対応
Linuxカーネル2.6の概要
HTテクノロジの概要
GCCを使ったマルチスレッド・プログラミングの基本
◆リスト
図2 test200.log

Copyright 2004 岸 哲夫

Copyright 1997-2004 CQ Publishing Co.,Ltd.