最近工作需要,写了一个线程库,由于之前从没有真正写过,因此本次线程库的经历如下:
1.用最简单的
master(){
lock();
while(full(queue))
pthread_cond_wait();
enqueue();
unlock();
pthread_cond_broadcast();
}
worker(){
lock();
while(empty(queue))
pthread_cond_wait();
dequeue();
unlock();
pthread_cond_broadcast();
}
一天之后将broadcast换成了signal,并且增加了一个condition用来表示队列满,效率提高了3倍左右。
2.阅读了Hewlett Packard Development Company, L.P
colin.honess@hp.com, HP Worldwide Presales的文章,采用了里面介绍的方法,该方法如下:
1.思路:sleep和wakeup的代价很高,尤其是整个线程池中只有一个线程sleep的时候,wakeup的开销就更大,因此需要避免sleep和wakeup,一般的方法是调整线程池的的大小,使得每个线程在每时每刻都是活跃的,但该方法明显不可用。另一种方法是用一些变量来保存当前线程池的状态,包括工作队列里的工作数量,活跃的线程数目,另外加一个经验值,即每个线程对应的工作数量,主线程唤醒新的线程的条件是当活跃线程数量为0或者队列里的工作数量大于活跃线程乘以每个线程对应的工作数量,代码如下
if(active_threads == 0 || num_in_queue / per_threads_num > active_threads && active_threads < pool.size)
pthread_cond_signal();
采用这种方式后,效率得到了进一步的提升,当然,需要在程序运行过程中根据队列里的数据量适当调整per_threads_num
进一步的改进是,如果只是master线程wakeup其他工作线程,会降低master的运行速度,从而降低整个程序的性能,因此可以将唤醒其他工作线程的任务交给工作线程去完成,即master线程只有在active_threads == 0的时候才执行signal,工作线程执行
if(num_in_queue / per_threads_num > active_threads && active_threads < pool.size)
pthread_cond_signal();
这样可以进一步提高性能。
同时如果主线程慢,可以采取批量入队的方式
1.用最简单的
master(){
lock();
while(full(queue))
pthread_cond_wait();
enqueue();
unlock();
pthread_cond_broadcast();
}
worker(){
lock();
while(empty(queue))
pthread_cond_wait();
dequeue();
unlock();
pthread_cond_broadcast();
}
一天之后将broadcast换成了signal,并且增加了一个condition用来表示队列满,效率提高了3倍左右。
2.阅读了Hewlett Packard Development Company, L.P
colin.honess@hp.com, HP Worldwide Presales的文章,采用了里面介绍的方法,该方法如下:
1.思路:sleep和wakeup的代价很高,尤其是整个线程池中只有一个线程sleep的时候,wakeup的开销就更大,因此需要避免sleep和wakeup,一般的方法是调整线程池的的大小,使得每个线程在每时每刻都是活跃的,但该方法明显不可用。另一种方法是用一些变量来保存当前线程池的状态,包括工作队列里的工作数量,活跃的线程数目,另外加一个经验值,即每个线程对应的工作数量,主线程唤醒新的线程的条件是当活跃线程数量为0或者队列里的工作数量大于活跃线程乘以每个线程对应的工作数量,代码如下
if(active_threads == 0 || num_in_queue / per_threads_num > active_threads && active_threads < pool.size)
pthread_cond_signal();
采用这种方式后,效率得到了进一步的提升,当然,需要在程序运行过程中根据队列里的数据量适当调整per_threads_num
进一步的改进是,如果只是master线程wakeup其他工作线程,会降低master的运行速度,从而降低整个程序的性能,因此可以将唤醒其他工作线程的任务交给工作线程去完成,即master线程只有在active_threads == 0的时候才执行signal,工作线程执行
if(num_in_queue / per_threads_num > active_threads && active_threads < pool.size)
pthread_cond_signal();
这样可以进一步提高性能。
同时如果主线程慢,可以采取批量入队的方式