Thread: Probably very easy question about pthread mutexes

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    Jun 2009
    Posts
    101
    Thanks. I rewrote my program using CodePlug's example in post #10 in the link you posted. However, with that code it seems as though no two threads can ever concurrently process data because they lock the entire time they are working, which locks everything else until each thread is complete since everything is referencing the same mutex. That means only one thread works at a time, no matter how many are spawned. This is the result I am getting with my program.

    I only need a filename variable from the producer thread, so I tried unlocking each thread after they acquire the filename. This works well, but once the loop in the producer is complete, the program quits before waiting for the rest of the threads to complete. This happens because those threads freed their locks very early, after they got their filenames. The real number crunching takes a little time so of course the producer thread quits immediately, terminating the worker threads while they're in the middle of crunching.

    I also don't understand the mutex in the producer thread. The lock is outside of the loop, and gets unlocked by the first thread that's spawned. So, it seems useless since anything useful is only done while the producer loop is running. Why are they there?

    Thanks for your help. This is working pretty well, I just need to get these last few problems worked out!

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Since threads need to be joined, why do you need to keep track of which ones are running at all?

    Code:
    for (int i = 0; i < NTHREADS; ++i)
        thread[i] = pthread_create(...);
    
    // Workers are running, wait for them to finish
    
    for (int i = 0; i < NTHREADS; ++i)
        pthread_join(thread[i], NULL);
    The second loop will only terminate when all the threads have terminated.

    (Hint drop: Intel TBB. Use Google)
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  3. #3
    Registered User
    Join Date
    Jun 2009
    Posts
    101
    Quote Originally Posted by synthetix View Post
    I only need a filename variable from the producer thread, so I tried unlocking each thread after they acquire the filename. This works well, but once the loop in the producer is complete, the program quits before waiting for the rest of the threads to complete. This happens because those threads freed their locks very early, after they got their filenames. The real number crunching takes a little time so of course the producer thread quits immediately, terminating the worker threads while they're in the middle of crunching.
    To deal with this, should I call pthread_join() for as many worker threads exist?

    Here:

    Code:
    for(i=0;i<num_threads;i++){
    	pthread_join(threads[i],NULL);
    }
    
    return 0; //end of main
    Actually, I just tried this, and it doesn't work since each thread is running an endless while() loop. Should I add a condition to the while()?
    Last edited by synthetix; 11-03-2011 at 07:05 PM.

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by synthetix View Post
    Thanks. I rewrote my program using CodePlug's example in post #10 in the link you posted. However, with that code it seems as though no two threads can ever concurrently process data because they lock the entire time they are working, which locks everything else until each thread is complete since everything is referencing the same mutex.
    Hmmm -- did you understand condition_wait()? It unlocks the mutex.

    However, you do have a point, because the concept of a queue is not in that example; the producer hands off a singular I/O task that must complete before it creates another one. But the example is just to demonstrate the function of the wait condition. Imagine moving the printf() outside the lock (by copying the locked data) and maybe you can see more the value of de-synchronizing these activities (rather than wait for each printf() to complete, you could move on and accumulate data asynchronously).

    So, instead, use a FIFO structure (aka, a queue) contained by a first condition; when the producer is done with whatever provides it input, it waits on that to add until nothing is left. Tautology: the specifics of threading are a lot about the specifics of the task. In your case, it might be that the producer should just populate this queue (if the tasks are a finite list), then launch the threads detached (in which case, you do not need this first of two conditions, you only need the next one..).

    After that, the detached worker threads all wait for the same condition -- that the queue can be accessed -- pull a task, and release the condition. Then they work on the task, outside of the locked state, hence, asynchronously.

    I also don't understand the mutex in the producer thread. The lock is outside of the loop, and gets unlocked by the first thread that's spawned.
    Nope. You are perhaps discussing mutex's and conditions as if they are synonymous, but they are not. Conditions depend upon and control mutexes.
    Last edited by MK27; 11-03-2011 at 07:50 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    Registered User
    Join Date
    Jun 2009
    Posts
    101
    Quote Originally Posted by MK27 View Post
    Hmmm -- did you understand condition_wait()? It unlocks the mutex.
    Yeah, but I figured out that the producer thread waits until bDataConsumed = 1, which isn't set until the worker thread completes. That's why it refuses to give out any more data until the previous thread finishes. That's why it works much better when bDataConsumed = 1 is set before the hard work starts in the worker thread.

    After that, the detached worker threads all wait for the same condition -- that the queue can be accessed -- pull a task, and release the condition. Then they work on the task, outside of the locked state, hence, asynchronously.
    That sounds like what I need. I have a file list, which is sent to the worker threads. They process files and write new files independently, so the only thing they need before releasing the list is the next filename. However, I need to ensure that two threads don't grab the same filename. It seems to be working the way it is now, but my only problem is that the producer thread doesn't wait for the worker threads to finish. It seems I need to put something in the thread to check to see if the end of the list is reached, so they will terminate.

    Nope. You are perhaps discussing mutex's and conditions as if they are synonymous, but they are not. Conditions depend upon and control mutexes.
    I think I understand it... I hope!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. question about the pthread.
    By thungmail in forum C Programming
    Replies: 4
    Last Post: 10-31-2009, 09:38 PM
  2. Pthread question
    By gundamz2001 in forum C Programming
    Replies: 3
    Last Post: 09-16-2009, 04:04 AM
  3. pthread question
    By quantt in forum Linux Programming
    Replies: 7
    Last Post: 04-07-2009, 01:21 AM
  4. Mutexes and Blocking
    By NuNn in forum C Programming
    Replies: 2
    Last Post: 03-12-2009, 03:32 PM
  5. Easy question, (should be) easy answer... ;-)
    By Unregistered in forum A Brief History of Cprogramming.com
    Replies: 1
    Last Post: 06-12-2002, 09:36 PM