线程冲突很常见。有效的解决办法,就是使用线程锁。
吾现在碰到一个问题:
- 多个数据线程向一个队列中添加数据。
- 一个执行线程负责处理队列中的数据。
开始使用线程锁,也没有问题。后来仔细想了一下,觉得此处有阻塞问题:
- 执行线程消耗时间较多,在执行前加锁,执行完毕后释放锁。
- 在执行线程加锁期间,数据线程等着向队列中添加数据,岂不是要等较长时间?
怎么办?吾想了个办法。原有代码保持不变,执行线程自己增加一个执行元素(用不着执行队列)。于是流程变为:
- 执行线程执行前,加锁。
- 将数据队列中最先加入的元素,复制成执行元素。
- 解锁。
- 执行线程处理执行元素。
这样不仅实现了线程安全,也保证各个线程的性能。实例代码如下:
/**
因为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
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?