pthread not waiting for mutex lock threadFinished - c

Hi below is my coding snippet
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#define TIMEOUT 3
int threadFinished = 0;
pthread_mutex_t g_mutex;
void *threadFunction(void* attr)
{
pthread_mutex_lock(&g_mutex);
char *pData = (char*)attr;
if(pData)
{
printf("data from main thread is : %s\n",pData);
}
sleep(10);
threadFinished = 1;
pthread_mutex_unlock(&g_mutex);
return (void*)"This is thread message !";
}
int main()
{
pthread_t tid;
char *retVal = NULL;
int iTimeOut = TIMEOUT;
int i =0;
pthread_mutex_init(&g_mutex,NULL);
pthread_create(&tid,NULL,threadFunction,"Message from main thread");
//printf("itimeout %d , threadrunning %d\n",iTimeOut,threadRunning);
while(iTimeOut!=0 && !threadFinished)
{
printf("waiting %d\n",++i);
sleep(1);
iTimeOut--;
printf("changing the threadfinish varible\n");
//pthread_mutex_lock(&g_mutex); //statement 1
threadFinished = 1;
//pthread_mutex_unlock(&g_mutex); // statement 2
printf("changed the threadfinish varible\n");
}
if(iTimeOut==0)
{
if(!threadFinished)
{
printf("Timed out so cancelling the thread \n");
pthread_cancel(tid);
}
else
{
printf("thread finished \n");
}
}
else
{
printf("thread finished its job \n");
pthread_join(tid,(void*)&retVal);
}
pthread_mutex_destroy(&g_mutex);
threadFinished = 0;
printf("message from thread is : %s\n",retVal);
return 0;
}
When statement1 & statement2 are commented I am expecting child thread to change my testrunning variable first before main thread but it is working properly only when statement1 and statement2 are uncommented.
My question is why in child thread mutex lock is not locking my testrunning variable . it is allowing main thread to modify testrunning variable.

When accessing a variable concurrently from multiple threads, each thread needs to protect access to it via the same mutex. The main() thread fails to do so.
To correct this you could change main()'s while-loop like this:
while (iTimeOut != 0)
{
{
pthread_mutex_lock(&g_mutex);
int finished = threadFinished;
pthread_mutex_unlock(&g_mutex);
if (finished)
{
break;
}
}
printf("waiting %d\n",++i);
sleep(1);
iTimeOut--;
printf("changing the threadfinish varible\n");
pthread_mutex_lock(&g_mutex); //statement 1
threadFinished = 1;
pthread_mutex_unlock(&g_mutex); // statement 2
printf("changed the threadfinish varible\n");
}
Also you might like to consider narrowing locking to where it is necessary inside the thread-function like this:
void *threadFunction(void* attr)
{
char *pData = attr; /* No need to cast here in C, as opposed to C++. */
if(pData)
{
printf("data from main thread is : %s\n",pData);
}
sleep(10);
pthread_mutex_lock(&g_mutex);
threadFinished = 1;
pthread_mutex_unlock(&g_mutex);
return "This is thread message !"; /* No need to cast here in C, as opposed to C++. */
}
You should added error checking to all library calls in case a failure would influence the remaining execution.

Related

i wanna know what's the diffrent between mutex_lock and pthread_join? [duplicate]

This question already has answers here:
Difference between mutex lock and pthread_join
(2 answers)
Closed last year.
What's the difference between mutex_lock and pthread_join in these two source codes? They seem both to do the same thing, making the main function wait for the thread to finish execution.
This code:
#include "philo.h"
typedef struct s_bablo
{
pthread_mutex_t mutex;
} t_bablo;
void *myturn(void *arg)
{
t_bablo *bablo = (t_bablo *)arg;
int i = 0;
while(i < 10)
{
printf("My Turn ! %d\n", i);
i++;
sleep(1);
}
pthread_mutex_unlock(&bablo->mutex);
}
void *yourturn()
{
int i = 0;
while(i < 5)
{
printf("Your Turn ! %d\n", i);
i++;
sleep(1);
}
}
int main ()
{
t_bablo bablo;
pthread_mutex_init(&bablo.mutex, NULL);
pthread_t ph;
pthread_mutex_lock(&bablo.mutex);
pthread_create(&ph, NULL, myturn, &bablo);
yourturn();
pthread_mutex_lock(&bablo.mutex);
}
And this code :
#include "philo.h"
void *myturn(void *arg)
{
int i = 0;
while(i < 10)
{
printf("My Turn ! %d\n", i);
i++;
sleep(1);
}
}
void *yourturn()
{
int i = 0;
while(i < 5)
{
printf("Your Turn ! %d\n", i);
i++;
sleep(1);
}
}
int main ()
{
pthread_t ph;
pthread_create(&ph, NULL, myturn, NULL);
yourturn();
pthread_join(ph, NULL);
}
not to be rude but you can easily find the difference by googling both functions name...
Though pthread_mutex_lock is for variables. It locks this variable for the current running thread. Thus no other thread can use it, they have to wait for pthread_mutex_unlock to use it.
pthread_join waits for the specified thread to finish it's execution before continuing
I encourage you to read the man pages, they are really self explanatory.

Pthreads stack priority

i have little trouble with pthread priority.I have set scheduler FIFO. I have 2 thread, each have diffretnt priority. On my project when i push A or B, one thread start working. Thats fine, but when one thread working and push again B(priority15) and then A(priority 20) my assumption is that thread A jumps before B in stack queue and after first thread will by next thread A with priority 20 and then thread B (15). Is that problem FIFO or something else?
PS: I dont want use semaphore, i want to solve it just with priority and scheduler. Thanks
#include <stdio.h>
#include<pthread.h>
#include<semaphore.h>
#include<unistd.h>
#include <time.h>
#include <sched.h>
sem_t mutex;
void* levelOnefunction(void *a)
{
sem_wait(&mutex);
int* b = (int *) a;
printf("Thread! next main!\n");
printf("sched prior:%d\n",*b);
sleep(3);
sem_post(&mutex);
return 0;
}
int main()
{
char s;
pthread_t t;
pthread_attr_t tattr;
struct sched_param param;
sem_init(&mutex,0,1);
pthread_attr_init(&tattr);
if(pthread_attr_setschedpolicy(&tattr,SCHED_FIFO)!=0)
printf("ERROR FIFO!\n");
//pthread_setschedparam(t,SCHED_FIFO,&param);
if(pthread_attr_getschedparam(&tattr,&param)!=0)
printf("ERROR attr get sheduler!\n");
/* int k =pthread_attr_setinheritsched(&tattr,PTHREAD_EXPLICIT_SCHED);
if (k!=0)
printf("ERROR\n"); */
printf("Initial priority is %d \n",param.sched_priority);
int min = sched_get_priority_min(SCHED_FIFO);
int max = sched_get_priority_max(SCHED_FIFO);
printf("MIN - %d ---> MAX - %d\n",min,max);
scanf("%c",&s);
while (s != '\0')
{
if(s=='a')
{
printf("a\n");
param.sched_priority=20;
if(pthread_attr_setschedparam(&tattr,&param)!=0)
printf("ERROR attr_setschedul!\n");
printf("update priority is:%d\n",param.sched_priority);
if(pthread_create(&t,&tattr,levelOnefunction,(void *)&param.sched_priority)!=0)
printf("ERROR thread1\n");
pthread_join(t,NULL);
printf("main finish!\n");
printf("%c end\n\n",s);
}
else if(s=='b')
{
printf("b\n");
param.sched_priority=15;
if(pthread_attr_setschedparam(&tattr,&param)!=0)
printf("ERROR attr_setschedul!\n");
if(pthread_create(&t,&tattr,levelOnefunction,(void *)&param.sched_priority)!=0)
printf("ERROR Thread 2 ");
pthread_join(t,NULL);
printf("main finish!\n");
printf("%c end\n\n",s);
}
else if(s=='\n')
{
}
else if (s!='a' && s!='b')
{
printf("bad key\n");
}
scanf("%c",&s);
}
sem_destroy(&mutex);
return 0;
}
You are calling pthread_join() in the main thread immediately after creating each child thread.
This means that you never have more than one child thread created at a time - after creating one child thread, the main thread will then block in pthread_join() until that child thread is complete. Only then does it call scanf() again and potentially create another child thread.
Thread priorities don't come into it.

why does Pthread Signal from main, hangs the code?

The requirement for the sample application creating using pthread is given below:
A single thread is created from main using Pthread
Inside thread, Mutex is locked, a counter counts the value and while loop is incremented, While is set to the max count of 10.
after while loop finishes, the mutex is unlocked.
The above requirement I have tried implementing using pthread
Code is shown below:
#include <pthread.h>
#include <stdio.h>
pthread_mutex_t count_mutex;
pthread_cond_t count_threshold_cv;
int samples = 10;
int count = 0;
struct example
{
int i;
int a;
};
void *inc_x(void *x_void_ptr)
{
pthread_mutex_lock(&count_mutex);
printf("Thread is locked \n");
while(count < samples)
{
printf("inside While loop \n");
struct example *E2_ptr;
E2_ptr = (struct example *)x_void_ptr;
printf("inside thread count = %d\n",count);
E2_ptr->a = count;
E2_ptr->i = (count + 1);
count ++;
//pthread_cond_wait(&count_threshold_cv, &count_mutex);
}
pthread_mutex_unlock(&count_mutex);
printf ( "\n Test Successful for Thread\n");
pthread_exit(NULL);
}
int main()
{
int x = 100, y = 0,i = 0;
struct example *E1_ptr;
E1_ptr->a = 0;
E1_ptr->i = 0;
printf("Before\t E1_ptr->a = %d\t, E1_ptr->i = %d\n",E1_ptr->a,E1_ptr->i);
pthread_t inc_x_thread;
if(pthread_create(&inc_x_thread, NULL, inc_x, E1_ptr))
{
printf("Error creating thread\n");
}
if(pthread_join(inc_x_thread, NULL))
{
printf("Error joining thread\n");
}
for(i = 0; i<(samples-1); i++)
{
if(pthread_cond_signal(&count_threshold_cv))
{
printf("Error Signaling thread at sample = %d\n",i);
}
}
printf("after\t E1_ptr->a = %d\t, E1_ptr->i = %d\n",E1_ptr->a,E1_ptr->i);
pthread_mutex_destroy(&count_mutex);
pthread_cond_destroy(&count_threshold_cv);
pthread_exit (NULL);
return 0;
}
Doubt:
In the above code, the thread executes its function properly and exits.
Once the condition is applied, i.e. the below shown code is uncommented then,
pthread_cond_wait(&count_threshold_cv, &count_mutex);
Then the thread is stopped after 1st iteration of while loop as expected.
The signal is generated from main by the code shown below:
for(i = 0; i<(samples-1); i++)
{
if(pthread_cond_signal(&count_threshold_cv))
{
printf("Error Signaling thread at sample = %d\n",i);
}
}
observed that the signal is never sent.
Can someone please guide me, where am I going wrong. I'm a newbie to Pthreads.
Thanks in advance.
count_mutex and count_threshold_cv are not initialized, add:
int main()
{
pthread_mutex_init(&count_mutex, NULL);
pthread_cond_init(&count_threshold_cv, NULL);
//...
E1_ptr is not initialized.
There are many ways to solve it:
You can call malloc to allocate memory:
struct example *E1_ptr = malloc(sizeof(struct example));
E1_ptr->a = 0;
E1_ptr->i = 0;
or holds pointer to local variable:
struct example ex;
struct example *E1_ptr = &ex; //malloc(sizeof(struct example));
E1_ptr->a = 0;
E1_ptr->i = 0;
or
struct example ex;
ex.a = 0;
ex.i = 0;
then create thread with pthread_create(&inc_x_thread, NULL, inc_x, &ex)
pthread_cond_signal function does not wait. If a thread is blocked by condition variable pthread_cond_signal function unblocks this thread, otherwise returns immediately without waiting and does nothing. So your for loop with 10 iterations is executed as soon as possible, without any waiting for pthread_cond_wait is called.
So can rewrite your for loop to infinite loop, calling pthread_cond_signal repeatedly.
if(pthread_create(&inc_x_thread, NULL, inc_x, E1_ptr)) {
printf("Error creating thread\n");
}
while(1) { // INFINITE LOOP
if(pthread_cond_signal(&count_threshold_cv)) {
printf("Error Signaling thread at sample = %d\n",i);
}
if (taskDone) // testing global flag, if 1 break
break; // it means inc_x thread has ended
}
if(pthread_join(inc_x_thread, NULL)) { // it was pointed out in comment
printf("Error joining thread\n"); // you need to join at the end of main function
}
taskDone is global int, with 0 as default value. It is set to 1 before pthread_exit is called in inc_x function. Setting/checking taskDone should be wrapped with some synchronization mechanism, for example by adding new mutex or use count_mutex.

C Threads - Sync

I have this code, I am trying to create n threads, Do some work in each thread, and then reap each thread. If n thread is even, use detach, and if odd, use join,
When i run the program, it first prints out Successfully reaped thread, then doing working, then successfully reaped thread... looks like i have some synchronization issues
Do I even need to use Mutex?
Can anyone help me with getting everything running in the right order?
Thank you
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t lock;
void *dowork(){
//Do whatever needs to be done in each thread here
pthread_mutex_lock(&lock);
long tid = (long) pthread_self();
printf("Doing Work ...for %ld\n",tid);
pthread_mutex_unlock(&lock);
//pthread_exit(NULL);
return;
}
void spawn(int n){
if (pthread_mutex_init(&lock, NULL) != 0)
{
printf("\n mutex init failed\n");
exit (1);
}
int i=0;
//pthread_t * thread = malloc(sizeof(pthread_t)*n);
pthread_t threads[n];
while (i<n) {
if(pthread_create(&(threads[i]), NULL, dowork, NULL) != 0){
printf ("Create pthread error!\n");
exit (1);
}
i++;
}//End of while
// Wait for threads to complete //
i = 0;
while (i<n)
{
int success = -1;
if(i%2 == 0){
success=pthread_detach(threads[i]);
}
else{
success=pthread_join(threads[i], NULL);
}
if(success==0)
printf("Succesfully reaped thread\n");
i++;
}
pthread_mutex_destroy(&lock);
}
int main() {
spawn(5);
}

Using mutex for pthread results in random answer

I have written a simple pthread code which
#include <pthread.h>
#include <stdio.h>
#include <math.h>
#define ITERATIONS 500
// A shared mutex
pthread_mutex_t mutex;
int target;
void* opponent(void *arg)
{
int i;
printf("opp, before for target=%d\n", target);
pthread_mutex_lock(&mutex);
for(i = 0; i < ITERATIONS; ++i)
{
target++;
}
pthread_mutex_unlock(&mutex);
printf("opp, after for target=%d\n", target);
return NULL;
}
int main(int argc, char **argv)
{
pthread_t other;
target = 5;
// Initialize the mutex
if(pthread_mutex_init(&mutex, NULL))
{
printf("Unable to initialize a mutex\n");
return -1;
}
if(pthread_create(&other, NULL, &opponent, NULL))
{
printf("Unable to spawn thread\n");
return -1;
}
int i;
printf("main, before for target=%d\n", target);
pthread_mutex_lock(&mutex);
for(i = 0; i < ITERATIONS; ++i)
{
target--;
}
pthread_mutex_unlock(&mutex);
printf("main, after for target=%d\n", target);
if(pthread_join(other, NULL))
{
printf("Could not join thread\n");
return -1;
}
// Clean up the mutex
pthread_mutex_destroy(&mutex);
printf("Result: %d\n", target);
return 0;
}
Then I compile with this command
gcc -pedantic -Wall -o theaded_program pth.c -lpthread
However, every time I run the program, I get different results!!
$ ./theaded_program
main, before for target=5
main, after for target=-495
opp, before for target=5
opp, after for target=5
Result: 5
$ ./theaded_program
main, before for target=5
opp, before for target=5
opp, after for target=5
main, after for target=-495
Result: 5
The printf() statements are not executed when the mutex is locked and they are accessing target:
printf("opp, before for target=%d\n", target);
pthread_mutex_lock(&mutex);
This means one thread is potentially changing the value of target while another thread is attempting to read it (in the printf()). Move the printf() statements to be executed when the mutex is locked:
pthread_mutex_lock(&mutex);
printf("opp, before for target=%d\n", target);
/* snip */
printf("opp, after for target=%d\n", target);
pthread_mutex_unlock(&mutex);
This will prevent target being read by one thread and modified by another concurrently. However, there is no guarantee which thread will first acquire the mutex.
This result is as expected, your code guarantees that main and opponent are not doing
for(i = 0; i < ITERATIONS; ++i)
{
target--; //or ++ for the opponent
}
at the same time.
The printfs are not in any way protected by the mutex. To avoid this insert the printfs within the mutex lock/unlock

Resources