2013-01-04 45 views
2

我写了一个并行线程代码今天:为什么我的两个线程不能交错运行?

#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; 
} 

我希望它会运行像:

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

但实际上它运行:

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

的线程2似乎不能运行。 因此,我运行这个代码超过一小时, thread2只打印一行。 他们为什么不交错隔行?

我的环境:

  • 的Ubuntu 10.04 x86_64的
  • Linux操作系统Ubuntu 2.6.32-36-通用#79,Ubuntu的SMP星期二11月8日22时29分53秒UTC 2011 x86_64的GNU/Linux的
  • CPU:Intel Core i7 930(4核,8线程)

谢谢。

+2

1秒钟睡眠应该移出锁,你会看到稍微好一点的结果 – Petesh

+0

你认为线程会被交错的原因是什么? – NPE

回答

2

将睡眠移到互斥锁的外部,以便操作系统进程调度算法被释放以查看其他线程。问题是,当你睡觉的时候,另一个线程可以被调度,但锁定被设置,所以它不会。当线程1唤醒时,它会释放锁定,然后向右循环来设置它。线程2几乎没有机会进入。它正在被饿死。

+0

如果这是正确的,我会感到惊讶,尽管可能取决于操作系统。如果互斥锁由thread1锁定,则thread2位于锁的等待队列中。如果thread1解锁并且重新锁定互斥锁,我会认为它会在队列中_behind_ thread2 - 特别是如果它们具有相同的优先级。但是这可能是一个实现细节。我也会认为,thread1解锁会导致thread2被立即释放,但这可能不是它的工作原理。 – Gray

+0

好的,谢谢.. – rta

+1

@Gray:是的,取决于操作系统。并非每个实现都使用等待队列。有些允许其他线程无限制地饥饿。有些使它取决于互斥量的属性。我相信pthread互斥锁通常有一个队列,而自旋锁不是。 –

相关问题