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 thr开发者_StackOverflow中文版ead_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 for
loop in thrfunction
does 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 call pthread_mutex_destroy
after 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):
0 <- parent process spawns threads
1 <- parent process calls join to wait for thread in first column.
2 2 2
3 3
4 3 4
5 5 2
6 6 3
4
5
6
7 4 7 7 <-- step 7 waits for lock
5 8
6 9
7 10
11 <- step 11 releases lock
8
9
10
11
8
9
10
11
8
9
10
11
12 12 12 12
13 13 13 13
14 14 14 14 <- step 14 each thread returns.
15 <- parent process wait on thread 1 succeeds.
16 <- wait for thread 2
17 <- wait for thread 3
18 <- wait for thread 4
19 <- parent now cleans up thread data, lock data.
20 <- parent exits.
精彩评论