线程冲突很常见。有效的解决办法,就是使用线程锁。
吾现在碰到一个问题:
- 多个数据线程向一个队列中添加数据。
- 一个执行线程负责处理队列中的数据。
开始使用线程锁,也没有问题。后来仔细想了一下,觉得此处有阻塞问题:
- 执行线程消耗时间较多,在执行前加锁,执行完毕后释放锁。
- 在执行线程加锁期间,数据线程等着向队列中添加数据,岂不是要等较长时间?
怎么办?吾想了个办法。原有代码保持不变,执行线程自己增加一个执行元素(用不着执行队列)。于是流程变为:
- 执行线程执行前,加锁。
- 将数据队列中最先加入的元素,复制成执行元素。
- 解锁。
- 执行线程处理执行元素。
这样不仅实现了线程安全,也保证各个线程的性能。实例代码如下:
/**
因为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
关注
打赏
热门博文
- 历史最高名次:17
- 日常收集的妙语
- git更新:Your local changes to the following files would be overwritten by merge
- Github通过PR提交代码到开源库
- Github参与OpenJDK8的开发指南
- FreeType可以指定斜体值了!祝贺修改代码整合进入FreeType
- JDK/FreeType中关于斜的英文有哪些
- WINDOWS编译ffmpeg:LINK : fatal error LNK1104: 无法打开文件“LIBCMT.lib”
- 全网首发:编译ffmpeg: error: ‘VFW_E_NOT_FOUND‘ undeclared ; did you mean ‘NTE_NOT_FOUND‘?
- WINDOWS+VS2012+msys2编译ffmpeg成功,DLL不能用