使用两个队列,改进耗时线程引起的性能问题的思路及代码

简介: 使用两个队列,改进耗时线程引起的性能问题的思路及代码

线程冲突很常见。有效的解决办法,就是使用线程锁。


 吾现在碰到一个问题:


多个数据线程向一个队列中添加数据。

一个执行线程负责处理队列中的数据。

 开始使用线程锁,也没有问题。后来仔细想了一下,觉得此处有阻塞问题:


执行线程消耗时间较多,在执行前加锁,执行完毕后释放锁。

在执行线程加锁期间,数据线程等着向队列中添加数据,岂不是要等较长时间?

 怎么办?吾想了个办法。原有代码保持不变,执行线程自己增加一个执行元素(用不着执行队列)。于是流程变为:


执行线程执行前,加锁。

将数据队列中最先加入的元素,复制成执行元素。

解锁。

执行线程处理执行元素。

 这样不仅实现了线程安全,也保证各个线程的性能。实例代码如下:


/**
因为FEXT消耗时间较长,所以采取两个队列:
一个用来加数据,通过线程锁控制。
一个复制后,执行Fext
*/
static  ImageBuffer**   g_ppFextQueue      = NULL;
static  int             g_nFextQueueLength = -1;
static  pthread_mutex_t g_oFextMutext;
static  void  fext_queue(ImageBuffer* pImage)
{
    int queued = 0;
    //>=0表示初始化完成。
    if (g_nFextQueueLength >= 0)
    {
        pthread_mutex_lock(&g_oFextMutext);
     if (g_nFextQueueLength >= GH_FEXT_QUEUE_LENGTH)
        {
            g_nFextQueueLength = 0;
        }
        //注意结构体内部的指针问题
        memcpy(g_ppFextQueue[g_nFextQueueLength], pImage, sizeof(ImageBuffer));
        g_nFextQueueLength ++;
        queued = 1;
        pthread_mutex_unlock(&g_oFextMutext);
    }
    if (!queued)
    {
        databuffer_release((DataBuffer*)&(pImage->buffer));
    }
}
static  void  *fext_thread(void  *arg)
{
    int i;
    ImageBuffer*   pFextExe       = NULL;
    int queue_malloc_size = sizeof(ImageBuffer*)*GH_FEXT_QUEUE_LENGTH;
    //开始初始化,fext_queue()不会进行相应操作。
    g_nFextQueueLength = -1;
    fext_init(  (char*)arg);
    //free(arg);
    //fext初始化开始
    pthread_mutex_init(&g_oFextMutext, NULL);
    g_ppFextQueue   =  (ImageBuffer**)gh_malloc(queue_malloc_size);
    for (i=0; i<GH_FEXT_QUEUE_LENGTH; i++)
    {
        g_ppFextQueue[i]  = (ImageBuffer*)gh_malloc(sizeof(ImageBuffer));
    }
    pFextExe = (ImageBuffer*)gh_malloc(sizeof(ImageBuffer));
    //fext初始化完成
    g_nFextQueueLength  = 0;
    DataBuffer oImageFeature;
    memset(&oImageFeature, 0, sizeof(DataBuffer));
    databuffer_check(&oImageFeature, sizeof(float)*GH_FEXT_FEATURE_SIZE);
    while  (1)
    {
      if  (g_nFextQueueLength == 0)
      {
          usleep(GH_FEXT_THREAD_SLEEP_TIME);
          continue;
      }
      //将数据队列的指针复制到执行队列。      
      pthread_mutex_lock(  &g_oFextMutext);
      int early_index = g_nFextQueueLength + 1; //注意越界处理
      memcpy(pFextExeQueue, g_ppFextQueue[early_index], sizeof(ImageBuffer));
      g_nFextQueueLength  = 0;
      pthread_mutex_unlock(&g_oFextMutext);
      fext_action(pImage, &oImageFeature);
    }
    //做个样子而已。
    databuffer_release(&oImageFeature);
    free_array(g_ppFextQueue, GH_FEXT_QUEUE_LENGTH);
    free(g_ppFextQueue);
    free(pFextExeQueue);
}
目录
相关文章
|
2月前
|
缓存 负载均衡 安全
在Python中,如何使用多线程或多进程来提高程序的性能?
【2月更文挑战第17天】【2月更文挑战第50篇】在Python中,如何使用多线程或多进程来提高程序的性能?
|
2月前
多线程案例-定时器(附完整代码)
多线程案例-定时器(附完整代码)
242 0
|
4月前
|
数据采集 Python
【Python自动化】多线程BFS站点结构爬虫代码,支持中断恢复,带注释
【Python自动化】多线程BFS站点结构爬虫代码,支持中断恢复,带注释
28 0
|
4月前
|
Java
Java使用线程池代码
Java使用线程池代码
35 0
|
4月前
|
Java
|
8天前
|
安全
python_threading多线程、queue安全队列
python_threading多线程、queue安全队列
14 2
|
2月前
|
NoSQL 数据处理 调度
【Redis深度专题】「踩坑技术提升」探索Redis 6.0为何必须启用多线程以提升性能与效率
【Redis深度专题】「踩坑技术提升」探索Redis 6.0为何必须启用多线程以提升性能与效率
245 0
|
1天前
|
存储 缓存 前端开发
Java串口通信技术探究3:RXTX库线程 优化系统性能的SerialPortEventListener类
Java串口通信技术探究3:RXTX库线程 优化系统性能的SerialPortEventListener类
11 3
|
9天前
|
存储 缓存 NoSQL
为什么Redis使用单线程 性能会优于多线程?
在计算机领域,性能一直都是一个关键的话题。无论是应用开发还是系统优化,我们都需要关注如何在有限的资源下,实现最大程度的性能提升。Redis,作为一款高性能的开源内存数据库,因其出色的单线程性能而备受瞩目。那么,为什么Redis使用单线程性能会优于多线程呢?
21 1
|
24天前
|
并行计算 Java 调度
Java 中的多线程编程:提升性能与效率的关键
多线程编程在Java中是一项重要的技能,它可以显著提升程序的性能与效率。本文将介绍多线程编程的基本概念、常见问题及解决方法,以及如何在Java中利用多线程技术来优化程序性能。
11 0

相关实验场景

更多