我的环境在Linux中,使用pthreads,用gcc编译。
我有3个线程作为接收套接字数据的套接字线程, thread1和thread2每秒大约1500行, thread3每秒会收到400行, 在thread1,thread2,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不会对信号进行排队,所以它没有任何危害 thread1,thread2,thread3每次接收套接字数据时触发pthread_cond_signal, 和thread4将在pthread_cond_wait(& condxx,mutexx)中被阻止,直到get pthread_cond_signal,这将节省cpu时间,也不会影响thread1,thread2,thread3,因为使用的mutex_lock较少!
我的想法是,使用pthread_cond_wait就像usleep一样, 但是当数据到达时,thread4不会错过!
请问,我做了什么有副作用?欢迎任何建议
答案 0 :(得分:3)
我认为你使线程4更高效的方法是一个很好的方法。如果只有线程1(生产者)和线程4(消费者),你的方法是让线程4有效地等待数据被线程1提供的标准方法。这里的皱纹是存在多个生产者线程(主题2和3)。
pthread_cond_signal()
的手册页表示发出没有线程正在等待的条件将无效,因此在线程1,2和3同时发出condxx
信号的情况下(如on一个多处理器系统),内核将对pthread_cond_signal()
的其中一个调用实际解除对线程4的阻塞,而其他两个调用无效。
换句话说,我认为你的方法会奏效。最好等待内核管理的数据(pthread_cond_wait()
,select()
等),而不是在循环中轮询(usleep()
想法)。
话虽如此,您的示例中仍然缺少一些关键代码。在调用mutexx
之前需要锁定pthread_cond_wait()
,并且必须锁定并解锁对pthread_cond_signal()
的调用。 This web page有一个与您的用例非常相似的示例,并演示了正确的锁定技术。