I have this homework to school – I completed it sent it and got 0% :] …
So I would like to ask if my idea is correct. For example if I want to write program with threads – I have to call 50 times thrfunction and I have 5 threads availible ( and I have to use them all as much as possible ). Could you please tell me if I am doing something wrong – I guess I am because printf says I use only one thread? I am not too sure about the method I would do this thing.
Thanks in advance
Nikolas Jíša
Here is my source code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define THREADS 5
#define CYCLES 50
sem_t sem1;
pthread_mutex_t m1, m2;
long int result = 0;
int thread_status[THREADS]; // status of threads, value -1 for working thread, other values for free threads
typedef struct Arg {
long int number;
int thread_ID; } ARG;
void * thrfunction ( void * arg ) {
int number = (( ARG * ) arg)->number, thread_ID = (( ARG * ) arg)->thread_ID, i;
thread_status[thread_ID] = -1;
pthread_mutex_unlock ( & m1 );
for ( i = 0; i < number; i ++ );
pthread_mutex_lock ( & m2 );
result = result + number;
printf ( "Thread %d result = %ld\n", thread_ID, result );
pthread_mutex_unlock ( & m2 );
pthread_mutex_lock ( & m1 );
thread_status[thread_ID] = thread_ID;
sem_post ( & sem1 );
pthread_mutex_unlock ( & m1 );
return NULL; }
int main ( int argc, char * argv[] ) {
pthread_t thr[THREADS];
pthread_attr_t Attr; pthread_attr_init ( & Attr ); pthread_attr_setdetachstate ( & Attr, PTHREAD_CREATE_JOINABLE );
pthread_mutex_init ( & m1, NULL ); pthread_mutex_init ( & m2, NULL );
sem_init ( & sem1, 0, THREADS );
int i, j;
ARG * pom = ( ARG * ) malloc ( sizeof ( * pom ) );
for ( i = 0; i < THREADS; i ++ )
thread_status[i] = i;
for ( i = 0; i < CYCLES; i ++ ) {
pom->number = rand () % 100000 * 10000;
sem_wait ( & sem1 );
pthread_mutex_lock ( & m1 );
for ( j = 0 ; j == -1; j ++ );
pthread_create ( & thr[j], & Attr, thrfunction, ( void * ) pom ); }
free ( pom );
pthread_attr_destroy ( & Attr ); pthread_mutex_destroy ( & m1 ); pthread_mutex_destroy ( & m2 ); sem_destroy ( & sem1 );
for ( i = 0; i < THREADS; i ++ )
pthread_join ( thr[i], NULL );
return 0;}
The first problem that I see is that you are using locks far too often.
Threading is much less efficient than sequential programming if all your program does is take locks. Locks cost time to take and release. That time is taken away from the work your program should be doing.
The second problem I see is that your
forloop inthrfunctiondoes nothing. It counts i from 0 to number? That is all it does?The third problem that I see is you call
free(pom)and you callpthread_mutex_destroyafter creating all of the threads. BAD! The threads are still using it! You have no guarantee that the threads have even started to run at this point. Your operating system may take seconds or even minutes (if it was low on RAM and swapping to disk) to start running all those threads you have created.Something you may find useful to think about threads is to write down each “critical section”, the pieces between locks, on cards, or use anything movable to represent those pieces. Make a column of those cards or pieces for each thread. Those pieces can move anywhere up or down in the timeline unless locks, joins, semaphores or anything else prevents it. If you want to get really technical, compiler optimization and processor out-of-order execution can even rearrange the pieces execution order, within limits.
Some program (not yours) might look like the following (and look at how the threading slows down to single speed at the lock in step 7):