RTOS: RTOSのためのpthread、その3

スレッドからの グローバル変数へのアクセス

まず、下の方に*******排他的処理がない場合********

の部分のソースをコンパイルして実行する.

65535まで2つのスレッドでそれぞれが1づつ大きくしていくというもの。それぞれ、65535回1を足し続けるので2倍の131070に答えはなるはず。

が実行するとならない・・・実行するたびに答えがかわる


上の実行の例では、1301064となってしまっている。

これはf1で足し算している間にf2の処理が入ってしまっておかしな計算をする事が発生しているから。これでは正しい演算結果が得られない。

そこで、排他的に、あるスレッドが計算している間は、他に処理を譲らないという処理をする。

mutex

という処理をする。semaphoreという処理もあるが、これらは興味があれば調べていろいろ試してほしい。

使い方はいたって簡単で、

pthread_mutex_t mutex;

とハンドラを宣下する。

pthread_mutex_init(&mutex, NULL);

で初期化。使い終わったら

pthread_mutex_destroy(&mutex);

で破棄。

ロックしたいところで、


処理をロックするところ、解放するところにそれぞれ、

pthread_mutex_lock(&mutex);

解除するところで

        pthread_mutex_unlock(&mutex);


この場合は、何度実行しても131070と正しい答えになる。



*******排他的処理がない場合********

/*This is a test for pthread.

 * it just increment number until 65535.

 * function 1 and 2 increase the same  counter. thus result becomes 65535 x 2 = 131070

 * However, results changes every time when you run it.

 */


#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

#include <unistd.h>

#include <string.h>


const size_t    loop_max = 65535;


int counter = 0;


void func1();

void func2();


int

main()

{

        pthread_t thread1, thread2;

        int ret1,ret2;


        ret1 = pthread_create(&thread1,NULL,(void *)func1,NULL);

        ret2 = pthread_create(&thread2,NULL,(void *)func2,NULL);


        ret2 = pthread_join(thread2,NULL);

        ret1 = pthread_join(thread1,NULL);



        printf("done\n");

        printf("%d\n", counter);

        return 0;

}

void

func1()

{

        size_t i;

        int j;

        for(i=0; i<loop_max; i++){

           for (j= 1; j <= 10000; j++) {}

                counter++;

            printf("f1:%d\n",counter);

        }

}

void

func2()

{

        size_t i;

        int j;

        for(i=0; i<loop_max; i++){

        for (j= 1; j <= 10000; j++) {}

                counter++;

              printf("f2:%d\n",counter);

        }

}

*************ここまで****************
************ここからmutex版**********
/*This is a test for pthread.
 * it just increment number until 65535.
 * function 1 and 2 increase the same  counter. thus result becomes 65535 x 2 = 131070
 * However, results changes evry time when you run it.
 * To prevent this, mutex is used to lock during the increment.

 */
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>

const size_t    loop_max = 65535;

pthread_mutex_t mutex;
int counter = 0;


void func1();
void func2();

int
main()
{
        pthread_t thread1, thread2;

        pthread_mutex_init(&mutex, NULL);

        int ret1,ret2;

        ret1 = pthread_create(&thread1,NULL,(void *)func1,NULL);
        ret2 = pthread_create(&thread2,NULL,(void *)func2,NULL);

        ret1 = pthread_join(thread1,NULL);
        ret2 = pthread_join(thread2,NULL);

        printf("done\n");
        printf("%d\n", counter);

        pthread_mutex_destroy(&mutex);

        return 0;
}

void
func1()
{
        size_t i;
        int j;
    pthread_mutex_lock(&mutex);
        for(i=0; i<loop_max; i++){
        for (j= 1; j <= 10000; j++) {}
                counter++;
                printf("f1:%d\n",counter);
        }
        pthread_mutex_unlock(&mutex);
}

void
func2()
{
        size_t i;
        int j;
    pthread_mutex_lock(&mutex);
        for(i=0; i<loop_max; i++){
        for (j= 1; j <= 10000; j++) {}
                counter++;
                printf("f2:%d\n",counter);
        }
        pthread_mutex_unlock(&mutex);
}

コメント

このブログの人気の投稿

Attiny85とAQM0802A(LCD)のI2C接続

CH9329で日本語キーボード109で正しく表示する方法