サーチ…


引数のない単純なスレッド

この基本的な例は、同期(メイン)と非同期(新しいスレッド)という名前の2つのスレッドで異なるレートでカウントされます。メインスレッドは1Hz(1s)で15にカウントされ、2番目のカウントは0.5Hz(2s)で10にカウントされます。メインスレッドは先に終了するので、 pthread_joinを使用して非同期で終了するようにします。

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

/* This is the function that will run in the new thread. */
void * async_counter(void * pv_unused) {
    int j = 0;
    while (j < 10) {
        printf("async_counter: %d\n", j);
        sleep(2);
        j++;
    }

    return NULL;
}

int main(void) {
    pthread_t async_counter_t;
    int i;
    /* Create the new thread with the default flags and without passing
     * any data to the function. */
    if (0 != (errno = pthread_create(&async_counter_t, NULL, async_counter, NULL))) {
        perror("pthread_create() failed");
        return EXIT_FAILURE;
    }

    i = 0;
    while (i < 15) {
        printf("sync_counter: %d\n", i);
        sleep(1);
        i++;
    }

    printf("Waiting for async counter to finish ...\n");

    if (0 != (errno = pthread_join(async_counter_t, NULL))) {
        perror("pthread_join() failed");
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

ここからコピーされました: http ://stackoverflow.com/documentation/c/3873/posix-threads/13405/simple-thread-without-arguments最初はM. Rubio-Royによって作成されました。

単純なmutexの使用

POSIXスレッドライブラリは相互排除のために使用されるmutexプリミティブの実装を提供します。ミューテックスを使用して作成されpthread_mutex_init使用して、破壊されたpthread_mutex_destroy 。ミューテックスを取得するには、 pthread_mutex_lockまたはpthread_mutex_trylock (タイムアウトが必要な場合に応じて)を使用し、mutexを解放するにはpthread_mutex_unlockます。

ミューテックスを使用してクリティカルセクションへのアクセスをシリアライズする簡単な例を次に示します。まず、ミューテックスを使用しない例。このプログラムは、2つのスレッドによるglobal_resourceへの非同期アクセスのためにデータ競合が発生することに注意してください。その結果、このプログラムには未定義の動作があります

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

// Global resource accessible to all threads
int global_resource;

// Threading routine which increments the resource 10 times and prints
// it after every increment
void* thread_inc (void* arg)
{
    for (int i = 0; i < 10; i++)
    {
        global_resource++;
        printf("Increment: %d\n", global_resource);
        // Make this thread slower, so the other one
        // can do more work
        sleep(1);
    }

    printf("Thread inc finished.\n");

    return NULL;
}

// Threading routine which decrements the resource 10 times and prints
// it after every decrement
void* thread_dec (void* arg)
{
    for (int i = 0; i < 10; i++)
    {
        global_resource--;
        printf("Decrement: %d\n", global_resource);
    }

    printf("Thread dec finished.\n");

    return NULL;
}

int main (int argc, char** argv)
{
    pthread_t threads[2];

    if (0 != (errno = pthread_create(&threads[0], NULL, thread_inc, NULL)))
    {
        perror("pthread_create() failed");
        return EXIT_FAILURE;
    }

    if (0 != (errno = pthread_create(&threads[1], NULL, thread_dec, NULL)))
    {
        perror("pthread_create() failed");
        return EXIT_FAILURE;
    }

    // Wait for threads to finish
    for (int i = 0; i < 2; i++)
    {
        if (0 != (errno = pthread_join(threads[i], NULL))) {
            perror("pthread_join() failed");
            return EXIT_FAILURE;
        }
    }

    return EXIT_SUCCESS;
}

可能な出力は次のとおりです。

Increment: 1
Decrement: 0
Decrement: -1
Decrement: -2
Decrement: -3
Decrement: -4
Decrement: -5
Decrement: -6
Decrement: -7
Decrement: -8
Decrement: -9
Thread dec finished.
Increment: -8
Increment: -7
Increment: -6
Increment: -5
Increment: -4
Increment: -3
Increment: -2
Increment: -1
Increment: 0
Thread inc finished.

今度は、これらのスレッドを同期させて、最初に増分または減分してから別の方法で行う場合は、mutexなどの同期プリミティブを使用する必要があります。

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

// Global resource accessible to all threads
int global_resource;
// Mutex protecting the resource
pthread_mutex_t mutex;

// Threading routine which increments the resource 10 times and prints
// it after every increment
void* thread_inc (void* arg)
{
    // Pointer to mutex is passed as an argument
    pthread_mutex_t* mutex = arg;

    // Execute the following code without interrupts, all the way to the
    // point B
    if (0 != (errno = pthread_mutex_lock(mutex)))
    {
        perror("pthread_mutex_lock failed");
        exit(EXIT_FAILURE);
    }

    for (int i = 0; i < 10; i++)
    {
        global_resource++;
        printf("Increment: %d\n", global_resource);
        // Make this thread slower, so the other one
        // can do more work
        sleep(1);
    }

    printf("Thread inc finished.\n");

    // Point B:
    if (0 != (errno = pthread_mutex_unlock(mutex)))
    {
        perror("pthread_mutex_unlock failed");
        exit(EXIT_FAILURE);
    }

    return NULL;
}

// Threading routine which decrements the resource 10 times and prints
// it after every decrement
void* thread_dec (void* arg)
{
    // Pointer to mutex is passed as an argument
    pthread_mutex_t* mutex = arg;

    if (0 != (errno = pthread_mutex_lock(mutex)))
    {
        perror("pthread_mutex_lock failed");
        exit(EXIT_FAILURE);
    }

    for (int i = 0; i < 10; i++)
    {
        global_resource--;
        printf("Decrement: %d\n", global_resource);
    }

    printf("Thread dec finished.\n");

    // Point B:
    if (0 != (errno = pthread_mutex_unlock(mutex)))
    {
        perror("pthread_mutex_unlock failed");
        exit(EXIT_FAILURE);
    }

    return NULL;
}

int main (int argc, char** argv)
{
    pthread_t threads[2];
    pthread_mutex_t mutex;

    // Create a mutex with the default parameters
    if (0 != (errno = pthread_mutex_init(&mutex, NULL)))
    {
        perror("pthread_mutex_init() failed");
        return EXIT_FAILURE;
    }

    if (0 != (errno = pthread_create(&threads[0], NULL, thread_inc, &mutex)))
    {
        perror("pthread_create() failed");
        return EXIT_FAILURE;
    }

    if (0 != (errno = pthread_create(&threads[1], NULL, thread_dec, &mutex)))
    {
        perror("pthread_create() failed");
        return EXIT_FAILURE;
    }

    // Wait for threads to finish
    for (int i = 0; i < 2; i++)
    {
        if (0 != (errno = pthread_join(threads[i], NULL))) {
            perror("pthread_join() failed");
            return EXIT_FAILURE;
        }
    }

    // Both threads are guaranteed to be finished here, so we can safely
    // destroy the mutex
    if (0 != (errno = pthread_mutex_destroy(&mutex)))
    {
        perror("pthread_mutex_destroy() failed");
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

可能な出力の1つは

Increment: 1
Increment: 2
Increment: 3
Increment: 4
Increment: 5
Increment: 6
Increment: 7
Increment: 8
Increment: 9
Increment: 10
Thread inc finished.
Decrement: 9
Decrement: 8
Decrement: 7
Decrement: 6
Decrement: 5
Decrement: 4
Decrement: 3
Decrement: 2
Decrement: 1
Decrement: 0
Thread dec finished.

thread_dec最初にミューテックスを取得した場合、もう1つの可能な出力は逆になります。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow