2011-12-02 27 views
1

我的环境是在Linux中,使用gcc编译的pthreads。pthread_cond_wait和pthread_cond_signal的实现,任何副作用?

我有3个线程作为接收端口,数据插座线,每秒 约1500行用于线程1和线程, thread3将获得每秒400行,在 线程1,线程2,thread3,我用的mutex_lock保护全球变量, ,以便thread4得到这些全局变量是正确的,当然,thread4也使用 mutex_lock。

线程1:

Pthread_mutex_lock(&Mutex1); 
    iGlobal1 = iGlobal1 + 1;  
    Pthread_mutex_unlock(&Mutex1); 

线程2:

Pthread_mutex_lock(&Mutex2); 
iGlobal2 = iGlobal2 + 1;  
Pthread_mutex_unlock(&Mutex2); 

Thread3:

Pthread_mutex_lock(&Mutex3); 
iGlobal3 = iGlobal3 + 1;  
Pthread_mutex_unlock(&Mutex3); 

Thread4:

while(1) 
{ 
    Pthread_mutex_lock(&Mutex1); 
    ilocal1 = iGlobal1; 
    Pthread_mutex_unlock(&Mutex1); 

    Pthread_mutex_lock(&Mutex2); 
    ilocal2 = iGlobal2; 
    Pthread_mutex_unlock(&Mutex2); 

    Pthread_mutex_lock(&Mutex3); 
    ilocal3 = iGlobal3; 
    Pthread_mutex_unlock(&Mutex3); 

    DoSomething(ilocal1,ilocal2,ilocal3); 
}//while 

在我看来,Thread4可以更高效,因为如果thread4执行得太频繁, 会花费很多cpu,而mutex_lock会影响thread1,thread2和thread3 ... 所以我认为使用pthread_cond_signal会使它更好,如下所示:

线程1:

Pthread_mutex_lock(&Mutex1); 
iGlobal1 = iGlobal1 + 1 ;  
pthread_cond_signal(&condxx); 
Pthread_mutex_unlock(&Mutex1); 

线程2:

Pthread_mutex_lock(&Mutex2); 
iGlobal2 = iGlobal2 + 1 ; 
pthread_cond_signal(&condxx); 
Pthread_mutex_unlock(&Mutex2); 

Thread3:

Pthread_mutex_lock(&Mutex3); 
iGlobal3 = iGlobal3 + 1 ;  
pthread_cond_signal(&condxx); 
Pthread_mutex_unlock(&Mutex3); 

Thread4:

while(1) 
{ 

    pthread_cond_wait(&condxx, mutexx); 

    Pthread_mutex_lock(&Mutex1); 
    ilocal1 = iGlobal1; 
    Pthread_mutex_unlock(&Mutex1); 

    Pthread_mutex_lock(&Mutex2); 
    ilocal2 = iGlobal2; 
    Pthread_mutex_unlock(&Mutex2); 

    Pthread_mutex_lock(&Mutex3); 
    ilocal3 = iGlobal3; 
    Pthread_mutex_unlock(&Mutex3); 

    DoSomething(ilocal1,ilocal2,ilocal3); 
}//while 

因为调用pthread_cond_signal不会排队信号,所以它有在 无妨线程1,线程2,thread3到调用pthread_cond_signal每次触发接收插座数据, 和thread4将在调用pthread_cond_wait被阻止(& condxx,mutexx)直到得到 pthread_cond_signal,这将节省CPU时间,也不会影响thread1,thread2,thread3,因为使用了更少的mutex_lock!

我的想法是,使用类似usleep的pthread_cond_wait, 但数据到达时,thread4不会错过!

请问我有什么副作用?任何建议是值得欢迎的

+0

DoSomething()在thread4中是否要求所有3个线程都改变了它们各自的全局或者只是一个? thread4是否以任何方式改变全局变量?全局变量是内置类型还是相对较小?换句话说,如果DoSomething()只是更新一个GUI计数器或一些这样的操作,你可能可以一起取消所有的锁定,并且只需要将线程1,2,3写入管道。线程4挂在管道上读取并执行其操作。 – Duck

+0

谢谢Duck,一旦Thread1,thread2,threa3中的一个chnaged,它需要调用DoSomething,DoSomething不会改变全局变量,但是Dosomething需要复杂的计算,花费时间来完成,我认为pipe是一个好主意,谢谢伟大的建议! – barfatchen

+0

第二个想法是,在Dosomethin执行期间,同时Thread1有3个数据接收,thread2有5个数据接收,thread3有1个数据接收,我只喜欢使用thread1的第3个数据,第5个数据线程2中的数据1,在thread3中的所有数据,一起填写DoSomething,在我的情况下使用管道不是一个好主意! – barfatchen

回答

2

我认为你的方法来提高线程4是一个很好的方法。如果只有线程1(生产者)和线程4(消费者),那么你的方法是让线程4有效等待数据由线程1提供的标准方式。这里的折痕是存在多个生产者线程(线程2和3)。

pthread_cond_signal()的手册页说,发信号通知没有线程正在等待的条件应该没有作用,因此在线程1,2和3同时发信号为condxx(如在多处理器系统上)的情况下,内核将有一个pthread_cond_signal()实际上解除线程4的电话,而其他两个电话将不起作用。

换句话说,我认为你的方法可行。并且等待内核管理的数据(pthread_cond_wait(),select()等)比在循环中轮询它(您的usleep()想法)更好。

这就是说,你的代码中缺少一些关键代码。在致电pthread_cond_wait()之前,需要锁定mutexx,并且必须锁定和解锁对pthread_cond_signal()的呼叫。 This web page有一个与您的用例非常相似的示例,并演示了正确的锁定技巧。

+0

谢谢!你帮了很多忙! – barfatchen

+0

没问题。我很乐意提供帮助。顺便说一句,堆栈溢出,表达感激之情的一个好方法是投票和/或接受你喜欢的答案。 –

+0

我不知道为什么,我点击了“投票”,但没有发生任何事情,这真的让我感到困扰......我会花时间弄清楚它! – barfatchen

相关问题