« Programming Puzzles | Main | DP 5 - PickPocketer »

Threading hair while on pthreads

Due to multicore and hyperthreaded processors, threading is now a common task programmers need to perform whenever possible. Quite often we see ready template code online or even C++ library based implementations that makes it easy or us to cut & paste, make few changes and unleash on to market after several testings...

This is fairly common these days that hardly any programmer can escape due to higher productivity requiremets !

We we do threaded programming, it is sure to have concurrent processing. So we need some kind of synchronizations to make sure we don't corrupt some shared data. Now the question is how to comeup with proper sync mechanism: mutex, spin-lock etc...

Here is an example of such application of threading -

Q: Print a sequence like: 010203040506070809010011012013 .... using threaded routines. One can do it in one thread, but here we need to exercise threading.

 

It's necessary to see how minimal locking we can do. To do that it is good to look at the state diagram. For example if a thread just print zero, then it has to let other threads to print non-zero. 

Now one more requirement imposed is: Use three threads : One prints zeros, another one prints even numbers, yet another prints odd numbers.

 

Codition to analyize:: When can zero thread print ? -- It can print after any non-zero got print. When can an even nunber be printed:: - When when zero thd. is not allowed to print, and last non-zero thread was odd number thread.

Now here is an implementation. It is instructive, if you use paper pencil first...

//

//  main.c

//  OS

//

//  Created by Admin on 5/26/18.

//  Copyright © 2018 AdminProkash Sinha. All rights reserved.

//

 

#include <stdio.h>

#include "OS.h"

int main(int argc, const char * argv[]) {

    // insert code here...

 

    testOddEvenPrint();

 

    printf("\nHello, World!\n");

    return 0;

}

 

//

//  thd.c

//  OS

//

//  Created by Admin on 5/26/18.

//  Copyright © 2018 AdminProkash Sinha. All rights reserved.

//

 

 

#include <stdbool.h>

#include<stdio.h>

#include<string.h>

#include<pthread.h>

#include<stdlib.h>

#include<unistd.h>

 

/*

 * Create a multi threaded ( 3 thd ) that prints 0102030405060708....

 * Need mutual exclusion

 */

 

//pthread_mutex_t mutx;

_Bool IsZero = true;

_Bool IsOddNo = true;

 

void AC( pthread_mutex_t *L)

{

    // -- waitable may block

    pthread_mutex_lock(L);

    return;

}

 

void RL( pthread_mutex_t *L)

{

    pthread_mutex_unlock(L);

    return;

}

 

void *printzero( void *Lock)

{

    pthread_mutex_t* L = (pthread_mutex_t*)Lock;

    for (int i = 0; i < 20; i++){

        AC ( L );

        if ( IsZero ){

            printf("%d", 0);

            IsZero = false;

        }

        RL(L);

    }

 

    return NULL;

}

 

void *printOdd( void *Lock )

{

    static int OddNo = 1;

    pthread_mutex_t* L = (pthread_mutex_t*)Lock;

    for (int i = 0; i < 10; i++){

        AC ( L );

        if ( !IsZero && IsOddNo){

            printf("%d", OddNo);

            IsZero = true;

            IsOddNo = false;

            OddNo += 2;

        }

        RL(L);

    }

    return NULL;

}

 

void *printEven( void *Lock )

{

    static int EvenNo = 2;

    pthread_mutex_t* L = (pthread_mutex_t*)Lock;

    for (int i = 0; i < 10; i++){

        AC ( L );

        if ( !IsZero && !IsOddNo){

            printf("%d", EvenNo);

            IsZero = true;

            IsOddNo = true;

            EvenNo += 2;

        }

        RL(L);

    }

    return NULL;

}

 

void

testOddEvenPrint()

{

    int err;

    pthread_t tid0thd, tidOddthd, tidEventhd;

    pthread_mutex_t mutx;

 

    if (pthread_mutex_init(&mutx, NULL) != 0)

    {

        printf("\n mutex init failed\n");

        return ;

    }

    err = pthread_create(&tid0thd, NULL, &printzero, &mutx);

    if (err != 0){

        printf("\ncan't create thread printzero :[%s]", strerror(err));

        return ;

    }

    err = pthread_create(&tidOddthd, NULL, &printOdd, &mutx);

    if (err != 0){

        printf("\ncan't create thread printzero :[%s]", strerror(err));

        return ;

    }

    err = pthread_create(&tidEventhd, NULL, &printEven, &mutx);

    if (err != 0){

        printf("\ncan't create thread printzero :[%s]", strerror(err));

        return ;

    }

 

    pthread_join(tid0thd, NULL);

    pthread_join(tidOddthd, NULL);

    pthread_join(tidEventhd, NULL);

 

    pthread_mutex_destroy(&mutx);

    return;

}

 

Posted on Saturday, May 26, 2018 at 05:19PM by Registered CommenterProkash Sinha | CommentsPost a Comment | References1 Reference

References (1)

References allow you to track sources for this article, as well as articles that were written in response to this article.

Reader Comments

There are no comments for this journal entry. To create a new comment, use the form below.

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
All HTML will be escaped. Hyperlinks will be created for URLs automatically.