2012-10-22 84 views
5

你好, 我是新来的多线程编程。 我想创建一个代码,创建一个线程THREAD1,它做了一些事情后,它触发两个其他线程,说THREAD2和THREAD3,然后退出。pthreads:触发其他线程的线程

我写了两个可能的解决方案。

1)使用条件变量(不起作用:在某些情况下,我得到一个死锁):

pthread_mutex_t ready_mutex = PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t ready_cond = PTHREAD_COND_INITIALIZER; 
bool ready = false; 

void* trigger(void*); 
void* func1(void*); 
void* func2(void*); 

int main() 
{ 
    pthread_t thread1; 
    pthread_t thread2; 
    pthread_t thread3; 
    pthread_create(&thread1, 0, &trigger, 0); 
    pthread_create(&thread2, 0, &func1, 0); 
    pthread_create(&thread3, 0, &func2, 0); 
    pthread_join(thread1, 0); 
    pthread_join(thread2, 0); 
    pthread_join(thread3, 0); 
} 

void *trigger(void*) 
{ 
    pthread_mutex_lock(&ready_mutex); 
    ready = true; 
    pthread_cond_broadcast(&ready_cond); 
    pthread_mutex_unlock(&ready_mutex); 
    return 0; 
} 

void *func1(void*) 
{ 
    while (!ready) // Needed to avoid spuriuos wake-up 
    { 
     pthread_mutex_lock(&ready_mutex); 
     pthread_cond_wait(&ready_cond, &ready_mutex); 
     pthread_mutex_unlock(&ready_mutex); 
    } 
    std::cout << "In 'func1'>> Do something" << std::endl; 
    return 0; 
} 

void *func2(void*) 
{ 
    while (!ready) // Needed to avoid spuriuos wake-up 
    { 
     pthread_mutex_lock(&ready_mutex); 
     pthread_cond_wait(&ready_cond, &ready_mutex); 
     pthread_mutex_unlock(&ready_mutex); 
    } 
    std::cout << "In 'func2'>> Do something" << std::endl; 
    return 0; 
} 

2)线程1直接创建两个其他线程。

pthread_mutex_t ready_mutex = PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t ready_cond = PTHREAD_COND_INITIALIZER; 

pthread_t thread1; 
pthread_t thread2; 
pthread_t thread3; 

void* trigger(void*); 
void* func1(void*); 
void* func2(void*); 

int main() 
{ 
    pthread_create(&thread1, 0, &trigger, 0); 

    pthread_join(thread1, 0); 
    pthread_join(thread2, 0); 
    pthread_join(thread3, 0); 
} 

void *trigger(void*) 
{ 
    std::cout << "In 'trigger'>> Do something" << std::endl; 

    pthread_create(&thread2, 0, &func1, 0); 
    pthread_create(&thread3, 0, &func2, 0); 

    return 0; 
} 

void *func1(void*) 
{ 
    std::cout << "In 'func1'>> Do something" << std::endl; 

    return 0; 
} 

void *func2(void*) 
{ 
    std::cout << "In 'func2'>> Do something" << std::endl; 

    return 0; 
} 

我想知道你的意见。 非常感谢您

+0

你的第二个实现似乎工作正常,你认为它有什么错? – engineerC

+0

你的第二个选择是更清洁和更好。我会那样做。 –

+0

@CaptainMurphy:我只是想知道是否有更好的方法来达到这个目标。从POSIX手册页看来,条件变量更适合这个目标,因为它们可以用来表示特定事件。 –

回答

5

使用条件变量(不起作用:在某些情况下,我得到一个死锁):

检查的共享状态时的代码不会锁定互斥变量ready。当它锁定互斥锁ready可能在那个时候发生了很好的变化,这就是为什么你会看到死锁。

正确的版本要等待一个条件变量的状态变化(检查省略错误):

pthread_mutex_lock(&ready_mutex); 
while(!ready) // Needed to avoid spuriuos wake-up 
    pthread_cond_wait(&ready_cond, &ready_mutex); 
// ready == true here 
pthread_mutex_unlock(&ready_mutex); 

上述假设ready发生改变时,只有当同一个互斥举行。

+0

是的,你是对的。所以,回到我的问题,我应该使用条件变量(解决方案#1)或延迟线程创建(解决方案#2)? –

+1

@ seg.fault我会使用[奥卡姆的剃刀](http://en.wikipedia.org/wiki/Occam's_razor):给出一个问题的多个解决方案选择更简单的一个。 –