我的环境是在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不会错过!
请问我有什么副作用?任何建议是值得欢迎的
DoSomething()在thread4中是否要求所有3个线程都改变了它们各自的全局或者只是一个? thread4是否以任何方式改变全局变量?全局变量是内置类型还是相对较小?换句话说,如果DoSomething()只是更新一个GUI计数器或一些这样的操作,你可能可以一起取消所有的锁定,并且只需要将线程1,2,3写入管道。线程4挂在管道上读取并执行其操作。 – Duck
谢谢Duck,一旦Thread1,thread2,threa3中的一个chnaged,它需要调用DoSomething,DoSomething不会改变全局变量,但是Dosomething需要复杂的计算,花费时间来完成,我认为pipe是一个好主意,谢谢伟大的建议! – barfatchen
第二个想法是,在Dosomethin执行期间,同时Thread1有3个数据接收,thread2有5个数据接收,thread3有1个数据接收,我只喜欢使用thread1的第3个数据,第5个数据线程2中的数据1,在thread3中的所有数据,一起填写DoSomething,在我的情况下使用管道不是一个好主意! – barfatchen