Find the answer to your Linux question:
Results 1 to 4 of 4
Hey all, I am wondering if pthread could make that a single thread keeps the "mutex" all the time if the time it remains unlocked is very small. thread1 { ...
  1. #1
    Just Joined!
    Join Date
    Jun 2010
    Posts
    2

    Pthread and mutex with short unlock time.

    Hey all,

    I am wondering if pthread could make that a single thread keeps the "mutex" all the time if the time it remains unlocked is very small.

    thread1
    {
    while (1)
    {
    lock; do_task(); unlock();
    }
    }

    thread2
    {
    sleep(5seconds); lock(); print(this should appear after 5 seconds'); unlock();
    }

    I experiment the thread2 never getting access to the mutex and never printing the nice message. I would expect that once thread2 calls "lock", it would get the mutex as soon as thread1 calls unlock() but it does not seem to be the case.

    If I add a sleep of some microseconds (100) in thread1 after unlocking the mutex, it solves the problem.

    Does anyone know if this behaviour is normal?
    Is there a way to configure my mutex so that thread2 receives it when unlocked?

    I use
    pthread_mutexattr_settype(&att, PTHREAD_MUTEX_RECURSIVE_NP);
    pthread_mutex_init(&handle, &att);
    to create my mutex.
    I am running ubuntu 9.04



    Thanks guys in advance !

    Chuck

  2. #2
    Linux Newbie
    Join Date
    Mar 2010
    Posts
    121
    Are you using any optimisation flags? If so, turn them off and see what happens.

    Otherwise, posting an example (as small as possible, but still a complete example, so people can simply cut, paste and compile) that produces the problem might help.

  3. #3
    Just Joined!
    Join Date
    Jun 2010
    Posts
    2

    Example of code.

    Hey John, thanks for your answer.

    Here is a sample code:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
    
    
    int thread1(void* userdata)
    {
    	__time_t t0;
    	int delta_t,_delta_t;
    	struct timeval tv;
    	pthread_mutex_t* mut = (pthread_mutex_t*) userdata;
    
    	gettimeofday(&tv,0);
    	t0 = tv.tv_sec;
    
    	while (1)
    	{
    		pthread_mutex_lock(mut);
    		usleep(10000);
    		gettimeofday(&tv,0);
    		delta_t	= (int) (tv.tv_sec - t0);
    		if (delta_t != _delta_t)
    			fprintf(stderr,"%d",delta_t);
    		_delta_t = delta_t;
    		pthread_mutex_unlock(mut);
    		//usleep(1000); //uncomment to see difference.
    	}
    	return 0;
    }
    
    int thread2(void* userdata)
    {
    	pthread_mutex_t* mut = (pthread_mutex_t*) userdata;
    	sleep(5);
    	pthread_mutex_lock(mut);
    	fprintf(stderr,"This should appear after 5 seconds!\n");
    	pthread_mutex_unlock(mut);
    	return 0;
    }
    
    int main()
    {
    	pthread_t t1;
    	pthread_t t2;
    	pthread_mutex_t test_mutex;
    	pthread_mutexattr_t mta;
    
    	pthread_mutexattr_init(&mta);
    	pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE_NP);
    	pthread_mutex_init(&test_mutex,&mta);
    
    	pthread_create(&t1,NULL,thread1,(void*) &test_mutex);
    	pthread_create(&t2,NULL,thread2,(void*) &test_mutex);
    	
    	pthread_join(t2,NULL);	
    	//pthread_join(t1,NULL);
    
    	return 0;
    }
    Can be compiled using

    gcc -o testmutex filename.c -lpthread.

    I guess no optimisation flag are used.

    thanks a lot,

    Chuck

  4. #4
    Linux Newbie
    Join Date
    Mar 2010
    Posts
    121
    Nice example - it demonstrates the problem well. Unfortunately, the problem isn't with the mutexe itself, but with the short amount of time it's being released for.

    What you've got to remember is that the scheduling of threads is absolutely unrelated to mutexes and which threads hold locks on which mutexes.

    Think about the flow of execution at the end of your while-loop in thread1 - you unlock the mutex, and then immediately request it again. But thread 2 has also requested the mutex. Does it hold it? Probably not, since you've only had one or two instructions since you let it go, and that's only one or two chances for a context switch. There's no way for thread 1 to "reserve" the mutex so it can't be locked*, so thread 1 is able to grab the mutex again. At some point during thread 1's sleep(), thread 2 will come back to life, but the mutex is locked, so it can't do anything and has to wait.

    To demonstrate, make the usleep(10000) (the second line in your while(1) loop) small - see what happens with values of 1, 10, 100 and 1000. I find that at around 200 it takes a couple of tries for thread 2 to see the mutex unlocked.

    The remedy for this is to (1) do as little as possible inside a mutex (i.e. no sleep() calls, like you have) and, if you think you're experiencing problems with this anyway, call sched_yield() after you unlock the mutex to let the scheduler know you want to give other threads a chance.

    Hope that's all clear. Sorry, I do tend to go on a bit


    * That would require a mutex on the mutex...

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...