Monday, April 18, 2016

Linux POSIX mutex an example source.

This example is mutex control with POSIX pthreads.

Linux POSIX example source is not synchronized inter thread.
Thread is able to synchronizing by the mutex. This
example is exclusive std-out on inter-threads.
When compiling source designate link library “libpthread” specify argument “-lpthread”.
$ gcc mutex.c -o mutex -lpthread

If do you watch behavior unsynchronized program, can you add a option with compiling.
$ gcc mutex.c -o mutex -lpthread -DNO_MUTEX

mutex.c

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

pthread_mutex_t mutex;

void* thread(void* arg); // Thread Entry function 1


//
// Main thread.
//
int main(int argc, char **argv) {

    int   ret;

    const char *arg1 = "Pneumonoultramicroscopicsilicovolcanoconiosis, Pneumonoultramicroscopicsilicovolcanoconiosis";
    const char *arg2 = "Supercalifragilisticexpialidocious, Pseudopseudohypoparathyroidism, floccinaucinihilipilification";
    const char *arg3 = "Lopadotemachoselachogaleokranioleipsanodrimhypotrimmatosilphioparaomelitokatakechymenokichlepikossyphophattoperisteralektryonoptekephalliokigklopeleiolagoiosiraiobaphetraganopterygon";

    pthread_t thrd1, thrd2, thrd3;
    void *th_ret1, *th_ret2, *th_ret3;

    pthread_mutex_init(&mutex, NULL);

    // Make three threads
    ret = pthread_create(&thrd1, NULL, thread, (void*)arg1);
    if (ret) {
        perror("pthread_create[Thread 1]");
        exit(1);
    }

    ret = pthread_create(&thrd2, NULL, thread, (void*)arg2);
    if (ret) {
        perror("pthread_create[Thread 2]");
        exit(1);
    }

    ret = pthread_create(&thrd3, NULL, thread, (void*)arg3);
    if (ret) {
        perror("pthread_create[Thread 3]");
        exit(1);
    }


    // Waiting threads quit.
    pthread_join(thrd3, &th_ret1);
    pthread_join(thrd2, &th_ret2);
    pthread_join(thrd1, &th_ret3);

#ifndef NO_MUTEX
    pthread_mutex_lock(&mutex);
#endif

    printf("Thread 3 [%d]\n", *(int*)th_ret1);
    free(th_ret1);                          // Free return value memory.
    printf("Thread 2 [%d]\n", *(int*)th_ret2);
    free(th_ret2);                          // Free return value memory.
    printf("Thread 1 [%d]\n", *(int*)th_ret3);
    free(th_ret3);                          // Free return value memory.

#ifndef NO_MUTEX
    pthread_mutex_unlock(&mutex);
#endif

    pthread_mutex_destroy(&mutex);

    return 0;
}

// Thread entry function
//   The function converts characters from a giving argument string.
void* thread(void* arg) {

    int   i;
    char* c = (char*)arg;
    int*  ret = malloc(sizeof(int));       // Allocate a return value area.

#ifndef NO_MUTEX
    pthread_mutex_lock(&mutex);
#endif

    for(i=0; i<strlen(c); i++) {
        if (isupper(*(c+i))) {
            printf("%c", (char)tolower(*(c+i)));
        }
        else {
            printf("%c", (char)toupper(*(c+i)));
        }
        usleep(1);
    }
    printf("\n");

#ifndef NO_MUTEX
    pthread_mutex_lock(&mutex);
#endif

    *ret = i;
    pthread_exit(ret);                     // Return value for main thread.
}

No comments:

Post a Comment