Mar 20, 2011

POSIX Threads - A simple Example

In our earlier post, we have written multithreaded program using win32 apis. This post deals with writing the multithreaded programs using POSIX thread apis. The important POSIX thread apis are namely pthread_create, pthread_exit and pthread_join

Create a thread

int pthread_create
(
    pthread_t *thread,
    const pthread_attr_t *attr,
    void *( *start_routine)(void *), 
    void *arg
);

Terminate a thread
void pthread_exit (void *retval);

Wait on a thread
int pthread_join (pthread_t thread, void **status);

The Complete Example
#include <pthread.h>
#include <iostream>

//File: SimpleThreadExample.cpp

#define MAX_THREADS 3
using namespace std;

void* func(void *args)
{
    int tp = *(int *)args * 10;
    while(tp--)
    {
        cout << *(int *) args;
        fflush(stdout);
        sleep(1);
    }

    cout << endl;
    pthread_exit((void *)10);
    return (void *)10;
}

int main(void)
{
    pthread_t tid[MAX_THREADS] = {0};
    int param[MAX_THREADS] = { 1, 2, 3 };

    int rc;
    for(int i = 0; i < MAX_THREADS; ++i)
    {
        rc = pthread_create(&tid[i], NULL, func, ¶m[i]);
        if(0 != rc)
        {
            cout << "ERROR: Thread Creation failed" << endl;
        }
        cout << "Thread[" << tid[i] << "] Created" << endl;
    }

    void *status[3];
    for(int i = 0; i < MAX_THREADS; ++i)
    {
        rc = pthread_join(tid[i], &status[i]);
    }

    for(int i = 0; i < MAX_THREADS; ++i)
    {
        cout << "Thread[" << tid[i] << "] returned with exit code=" << (long) status[i] << endl;
    }

    cout << "Main thread terminating" << endl;
    return 0;
}
The makefile for the project
#-----------------------------------------------------------------------
#                   A simple thread example
#-----------------------------------------------------------------------
PROJECT := SimpleThreadExample

SRCEXT := .h .cpp
OBJEXT := .o
EXEEXT := .exe

#compilers
CC := gcc
CXX := g++

#flags
CFLAGS := -o
CXXFLAGS := -o
LDFLAGS := -lpthread -o

#disable implicit suffix rules
.SUFFIXES:
.SUFFIXES: $(SRCEXT) $(OBJEXT) $(EXEEXT)

SRC := \
    SimpleThreadExample.cpp

OBJ := \
    $(SRC:.cpp=.o)

EXE := \
    $(PROJECT)$(EXEEXT)

#define dummy targets
.PHONY: all clean compile link

all : compile link

clean :
    @echo

    @echo "Cleaning Temporary Files..."
    $(RM) $(OBJ) $(EXE)

compile : $(OBJ)

link : $(EXE)

$(OBJ) :
    @echo
    @echo "Compiling Source Files..."
    $(CXX) $(CXXFLAGS) $(OBJ) $(SRC)

$(EXE) :
    @echo
    @echo "Linking..."
    $(LD) $(OBJ) $(LDFLAGS) $(EXE)

run :
    @echo
    @$(EXE)
Building the project. (The output is from Cygwin Environment. You may need to modify the makefile to compile it on a linux environment)
$ gmake clean all

Cleaning Temporary Files...
rm -f SimpleThreadExample.o SimpleThreadExample.exe

Compiling Source Files...
g++ -o SimpleThreadExample.o SimpleThreadExample.cpp

Linking...
ld SimpleThreadExample.o -lpthread -o SimpleThreadExample.exe
Output:

No comments :

Post a Comment