How to use pthread_mutex_trylock?

Using trylock:

FILE *fp; pthread_mutex_t demoMutex; void * printHello (void* threadId) { pthread_mutex_trylock (&demoMutex); pthread_t writeToFile = pthread_self (); unsigned short iterate; for (iterate = 0; iterate < 10000; iterate++) { fprintf (fp, " %d ", iterate, 4); fprintf (fp, " %lu ", writeToFile, sizeof (pthread_t)); fprintf (fp, "\n", writeToFile, 1); } pthread_mutex_unlock (&demoMutex); pthread_exit (NULL); } 

and then main ():

 int main () { pthread_t arrayOfThreadId [5]; int returnValue; unsigned int iterate; fp = fopen ("xyz", "w"); pthread_mutex_init (&demoMutex, NULL); for (iterate = 0; iterate < 5; iterate++) { if (returnValue = pthread_create (&arrayOfThreadId [iterate], NULL, printHello, (void*) &arrayOfThreadId [iterate]) != 0) { printf ("\nerror: pthread_create failed with error number %d", returnValue); } } for (iterate = 0; iterate < 5; iterate++) pthread_join (arrayOfThreadId [iterate], NULL); return 0; } 

Here, the first output prints some of the first stream, and then the rest, and then again the first. The lock does not work. If I replace the same with pthread_mutex_lock , each thing will be shown very sequentially!

What ridiculous mistake is here?

+6
source share
6 answers

It makes no sense to call pthread_mutex_trylock() without testing the result.

If he was unable to get the mutex, you should not enter a critical section, and you should not unlock it later. For example, you can rewrite it like this (note that you are also very confused about how fprintf() should be called):

 void *printHello(void *threadId) { if (pthread_mutex_trylock(&demoMutex) == 0) { unsigned short iterate; for (iterate = 0; iterate < 10000; iterate++) { fprintf (fp, " %d\n", iterate); } pthread_mutex_unlock (&demoMutex); } pthread_exit (NULL); } 

However, it probably makes sense to use pthread_mutex_lock() instead of pthread_mutex_trylock() , so your thread will wait for the mutex to be available if it is considered. pthread_mutex_lock() is in almost all cases what you want; the _trylock option _trylock intended only to optimize some unusual cases - if you ever come across a situation where _trylock is required, you will know.

+21
source
 ... while (pthread_mutex_trylock(&demoMutex) == 0) ... 

Your code does not make sense. Where is it blocked? Is this like a non-working spinlock that uses more CPU ?!

trylock returns 0 when locked, so:

 if(!pthread_mutex_trylock(&demoMutex)) { // mutex locked } 

The pthread_mutex_trylock () function returns zero if a lock is acquired on the mutex object referenced by the mutex. Otherwise, an error number is returned to indicate an error.

+4
source

The cafe had a great answer on how to use it. I just needed to get this explanation for myself, however I found out that pthread_mutex_lock() has a lot more overhead in the class and just tested it using the <time.h> lib library, and the performance for my loop has been significantly increased. Just adding two cents as he mentioned that maybe you should use pthread_mutex_lock() instead!

 #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #define NUM_THREADS 4 #define LOOPS 100000 int counter; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // using pthread_mutex_lock void* worker() { for (int i = 0; i < LOOPS; i++) { pthread_mutex_lock(&mutex); counter++; pthread_mutex_unlock(&mutex); } pthread_exit(NULL); } // using try_lock - obviously only use one at a time void* worker() { for (int i = 0; i < LOOPS; i++) { while (pthread_mutex_trylock(&mutex) != 0) { // wait - treated as spin lock in this example } counter++; pthread_mutex_unlock(&mutex); } pthread_exit(NULL); } int main(int argc, char *argv[]) { clock_t begin = clock(); pthread_t t[NUM_THREADS]; int rc; counter = 0; for (int i = 0; i < NUM_THREADS; i++) { rc = pthread_create(&t[i], NULL, worker, NULL); if (rc) { printf("Thread #%d failed\n", i); } } for (int i = 0; i < NUM_THREADS; i++) { pthread_join(t[i], NULL); } printf("%d\n", counter); clock_t end = clock(); double time = (double)(end - begin) / CLOCKS_PER_SEC; printf("Time Spent: %f", time); return 0; } 

Obviously, you could comment on one employee to test it, but if you try it, I get Time Spent: 1.36200 as the average for pthread_mutex_lock() and Time Spent: 0.36714 for pthread_mutex_trylock() .

Faster if you use Atomics.

+3
source

The code is designed to be locked to provide mutual exclusion , where you call pthread_mutex_trylock() . Otherwise, this behavior is undefined. Therefore you should call pthread_mutex_lock() .

0
source

a modified version of the power lock with a while loop should be more stable.

 void *printHello(void *threadId) { while (pthread_mutex_trylock(&demoMutex) == 0) { unsigned short iterate; for (iterate = 0; iterate < 10000; iterate++) { fprintf (fp, " %d\n", iterate); } pthread_mutex_unlock (&demoMutex); break; } pthread_exit (NULL); 

} `

0
source

Using pthread_mutex_trylock is used to ensure that tou does not cause races for a particular command. To do this, you must use pthread_mutex_trylock as a condition! do not assume that it will work by itself. example- while (pthread_mutex_trylock (& ​​amp; my_mutex) == 0) {printf ("Mutex is at my disposal !! \ n"); }

this way you can be sure that even if the mutex is locked, you are doing abuse by waiting for it in this particular thread.

0
source

Source: https://habr.com/ru/post/908323/


All Articles