Reputation: 2757
hi there i'm working on POSIX threads and i have a work like
so before i display my code i have to explain what i have done. first of all, i have 5 global variables (which are flags and all of them set to 1 initiallly ) and i assigned them to the value which pthread_create() function returns. and then in the main function i used if() conditions before i joined threads. but i guess i'm trying the wrong way. the issue is i coundnt handle with the process "before thread_a, thread_d must finish its work". i will appreciate if you can help and suggest some better ideas. and here is my code,
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
int counter = 0;
int flag_a = 1;
int flag_b = 1;
int flag_c = 1;
int flag_d = 1;
int flag_e = 1;
pthread_mutex_t mymutex=PTHREAD_MUTEX_INITIALIZER;
void* thread_function(void* str);
void print_char(char* ch);
int main(){
pthread_t thread_a, thread_b, thread_c, thread_d, thread_e;
char* a = "a";
char* b = "b";
char* c = "c";
char* d = "d";
char* e = "e";
flag_a = pthread_create( &thread_a, NULL, thread_function, (void*) a );
flag_b = pthread_create( &thread_b, NULL, thread_function, (void*) b );
flag_c = pthread_create( &thread_c, NULL, thread_function, (void*) c );
flag_d = pthread_create( &thread_d, NULL, thread_function, (void*) d );
flag_e = pthread_create( &thread_e, NULL, thread_function, (void*) e );
if(flag_c==0)
pthread_join( thread_a, NULL );
pthread_join( thread_b, NULL );
if(flag_d==0)
pthread_join( thread_c, NULL );
if(flag_d==0)
pthread_join( thread_d, NULL );
pthread_join( thread_e, NULL );
printf("\nCounter = %d\n", counter);
return 0;
}
void* thread_function(void* str) {
int i;
char* msg = (char*) str;
for(i=0; i<50; i++) {
pthread_mutex_lock(&mymutex);
counter++;
print_char(msg);
pthread_mutex_unlock(&mymutex);
}
}
void print_char(char* ch){
int i;
for(i=0; i<1; i++) {
printf("%s --> ", ch);
fflush(stdout);
sleep(1);
}
}
edit: i found a solution which prints the characters properly but the issue i cant print them asynchronousnly. i mean whenever i run the code it has same output like:
e-->d-->c-->b-->a (every character printed at 50 times )
and this the editted part of thread_function()
void* thread_function(void* str) {
int i;
char* msg = (char*) str;
while( (strcmp(msg,"a") == 0) && (counter_c < 5) ){
;;
}
while( (strcmp(msg,"c") == 0) && (counter_d < 5) ){
;;
}
while( (strcmp(msg,"b") == 0) && (counter_d < 5) ){
;;
}
for(i=0; i<5; i++) {
pthread_mutex_lock(&mymutex);
counter++;
if( strcmp(msg,"d") == 0 )
counter_d++;
if( strcmp(msg,"c") == 0 )
counter_c++;
print_char(msg);
pthread_mutex_unlock(&mymutex);
}
}
Upvotes: 1
Views: 407
Reputation: 379
// First print d then b or c after c's completion it will print a.then main function will wait for
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
int counter = 0;
int flag_a = 1;
int flag_b = 1;
int flag_c = 1;
int flag_d = 1;
int flag_e = 1;
pthread_mutex_t mymutex=PTHREAD_MUTEX_INITIALIZER;
void* thread_function(void* str);
void print_char(char* ch);
int main(){
pthread_t thread_a, thread_b, thread_c, thread_d, thread_e;
char* a = "a";
char* b = "b";
char* c = "c";
char* d = "d";
char* e = "e";
flag_d = pthread_create( &thread_d, NULL, thread_function, (void*) d );
pthread_join( thread_d, NULL );
flag_b = pthread_create( &thread_b, NULL, thread_function, (void*) b );
flag_c = pthread_create( &thread_c, NULL, thread_function, (void*) c );
pthread_join( thread_c, NULL );
flag_a = pthread_create( &thread_a, NULL, thread_function, (void*) a );
flag_e = pthread_create( &thread_e, NULL, thread_function, (void*) e );
//if(flag_c==0)
// pthread_join( thread_a, NULL );
// pthread_join( thread_b, NULL );
//if(flag_d==0)
// pthread_join( thread_c, NULL );
// if(flag_d==0)
// pthread_join( thread_d, NULL );
//pthread_join( thread_e, NULL );
printf("\nCounter = %d\n", counter);
pthread_exit(NULL); //or you can join thread e before printf() statement
return 0;
}
void* thread_function(void* str) {
int i;
char* msg = (char*) str;
for(i=0; i<50; i++) {
pthread_mutex_lock(&mymutex);
counter++;
print_char(msg);
pthread_mutex_unlock(&mymutex);
}
}
void print_char(char* ch){
int i;
for(i=0; i<1; i++) {
printf("%s --> ", ch);
fflush(stdout);
// sleep(1);
}
}
Upvotes: 1
Reputation: 24847
Maybe I misunderstand the requirement? Pseudo:
Start Ethread('e'); // can run async, since no contraints on 'e'
Start Dthread('d'); // print 'd' and
Join Dthread; // wait for 'd' to finish
Start Bthread('b'); // now start on the 'b'
Start Cthread('c'); // and the 'c'
Join Cthread; // but just wait for the 'c' to finish
Start Athread('a'); // and then print the 'a'
Each thread prints its passed char 50 times. If the common output routine needs a mutex, OK.
Does that not satisfy the requirement?
Upvotes: 0
Reputation: 37188
Logically, you have a dependency graph, and you need a way for each thread to a) wait for some condition to happen before it can begin to print it's stuff, and b) signal that it has completed printing, so that other threads waiting can start. In pthreads, this can be done with condition variables. So what you could do, instead of passing a pointer to the character to print, pass a pointer to a struct containing the character to print, a condition variable (and associated mutex) to wait on before starting the printing, and another condition variable with associated mutex to signal when done. And then in the main thread, before creating the threads, you of course need to setup all these structs appropriately, and after creating the threads, the main threads should signal those condition variables which are at the end (or beginning, depending on how you look at it..) of the dependency chain(s) in order to get the whole process started.
For in introduction how to use condition variables, see e.g. https://computing.llnl.gov/tutorials/pthreads/#ConditionVariables
Upvotes: 1
Reputation: 25863
Actually what you want is to suspend threads before starting to work, and until a given thread had finished.
In your case, you want A to wait for C, B and C to wait for D and launch D. For this you need semaphores, since a semaphore will block the thread until it is noticed to wake up.
Upvotes: 0