2
votes

I wrote a pthread code today:

#include <pthread.h>
#include <stdio.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void *thread1(void *arg)
{
    while (1) {
        pthread_mutex_lock(&mutex);
        sleep(1);
        printf("thread1...\n");
        pthread_mutex_unlock(&mutex);
    }
}

void *thread2(void *arg)
{
    while (1) {
        pthread_mutex_lock(&mutex);
        sleep(1);
        printf("thread2...\n");
        pthread_mutex_unlock(&mutex);
    }
}

int main()
{
    pthread_t tid1, tid2;
    pthread_create(&tid1, NULL, thread1, NULL);
    pthread_create(&tid2, NULL, thread2, NULL);

    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);

    return 0;
}

I expect it will run like:

thread1...
thread2...
thread1...
thread2...

But in fact it run:

thread1...
thread1...
thread1...
thread1...

The thread2 seems not run. Thus I run this code over one hour, thread2 just prints one line. Why don't they run interlaced?

My environment:

  • Ubuntu 10.04 x86_64
  • Linux ubuntu 2.6.32-36-generic #79-Ubuntu SMP Tue Nov 8 22:29:53 UTC 2011 x86_64 GNU/Linux
  • CPU: Intel Core i7 930 (4 cores, 8 threads)

Thank you.

1
The 1 second sleep should be moved outside the lock and you'll see slightly better results - Petesh
What exactly are your reasons for thinking the threads would be interleaved? - NPE

1 Answers

2
votes

Move the sleep outside of the mutex lock so the operating system process scheduling algorithm is freed to go look at the other thread. The problem is that when you sleep, the other thread can get scheduled but the lock is set so it doesn't. When thread 1 wakes up, it releases the lock but then loops right back to set it. Thread 2 ever hardly has a chance to get in. It is being starved.