线程安全问题。

feelang 2009-10-14 04:23:58
各位大牛,我现在在ADSP-BF561下基于NET2272开发USB实时图像传输,PC端是Windows平台,VS2008,但是图像传输不稳定,很容易就堵死。现在能够证明不是dsp端的问题,PC端的应用程序开了一个线程接收图像并显示,但是这样不稳定,如果将接受图像并显示放在主线程中,UI线程会死掉,但是这样很稳定。,线程安全都已经考虑到了,将UI 线程与工作线程的共享数据定义为全局,因为UI线程只负责初始化工作,当接受显示线程启动以后,UI线程便不会操作全局数据,请教各位大牛,我该从哪方面入手来解决这个问题。
...全文
183 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
痴才 2009-10-17
  • 打赏
  • 举报
回复
我一定好好学习 然后当个版主!
feelang 2009-10-17
  • 打赏
  • 举报
回复
大家继续讨论啊。。。。
huaweiheart1 2009-10-15
  • 打赏
  • 举报
回复
学习。。。。。
huofen2005 2009-10-15
  • 打赏
  • 举报
回复
单链表一个塞一个取,可以免锁!塞的时候把结点帧完全准备好了再挂到链表上的。
链表都不用,只要保证显示比传输的快,循环数组实现即可。
feelang 2009-10-15
  • 打赏
  • 举报
回复
USB的传输使用WriteFile,线程如果调用WriteFile的时候被中断是不是导致管道堵死呢?
love514425 2009-10-15
  • 打赏
  • 举报
回复
> 学习.
oyljerry 2009-10-15
  • 打赏
  • 举报
回复
自己增加一些调试log输出等,逐步隔离阻塞的语句等
feelang 2009-10-15
  • 打赏
  • 举报
回复
代码如下:

char* pBits = (char*)::GlobalLock(g_hPictureGlobal); // 锁定同步内存块
if (!pBits) // 锁定失败
{
GlobalUnlock(g_hPictureGlobal);
g_hPictureGlobal = NULL;
AfxMessageBox("Picture Alloc Error!");
}
while (TRUE)
{
int nResult = g_USBPort._USBGetPicFromDSP(pBits, BMP_SIZE); // 从DSP端获取图像数据
g_nIndex++; // 显示图像数目

if (nResult == IO_READ_DATA_FAILED)
{
GlobalUnlock(g_hPictureGlobal);
g_hPictureGlobal = NULL;
AfxMessageBox("_USBGetPicFromDSP Error!");
break;
}
Sleep(1); // 线程暂停

if (!g_bStartThread)
{
GlobalUnlock(g_hPictureGlobal);
g_hPictureGlobal = NULL;
break;
}
}
GlobalUnlock(g_hPictureGlobal);

AfxEndThread(0); // 结束进程

return 0;
}


int CUSBPort::_USBGetPicFromDSP(char* pPicBuffer, ULONG nPicSize)
{
int nResult = 0;
char *pcTemp = pPicBuffer;
ULONG nCountCurrent = 0;

ULONG nLeftSize = nPicSize;

//ULONG nLeftSize = (nPicSize / BLOCKSIZE) * BLOCKSIZE;// 图像整数大小
BOOL bIOStatus = FALSE;

int nBlockIndex = 0;
while (nLeftSize >= BLOCKSIZE)
{
_USBSendCommand(USB_GETPIC); // 发送获取图像命令
// 读取图像数据
bIOStatus = ReadPipe(m_hRead, pcTemp, BLOCKSIZE, &nCountCurrent);
if (!bIOStatus)
return IO_READ_DATA_FAILED;

pcTemp += nCountCurrent;
nLeftSize -= BLOCKSIZE;

if (nResult != OPERATION_PASSED)
return IO_READ_DATA_FAILED;
}

if (nLeftSize > 0)
{
if (!ReadPipe(m_hRead, pcTemp, nLeftSize, &nCountCurrent))
{
return IO_READ_DATA_FAILED;
}
}
return OPERATION_PASSED;
}
muzizongheng 2009-10-14
  • 打赏
  • 举报
回复
我的意见是:

画图的还是不要改,

开个线程, 然后在线程里发个消息, 让自定义消息来通知画图.
zhaohongbo83 2009-10-14
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 dirdirdir3 的回复:]
线程接收图像并显示..........这样做很不好,线程除非是自带界面的不然最好不要插足显示,不然很容易出问题....................最好的方法是开个线程接收数据,存放于一个加了同步锁的队列里面,然后界面线程从这个队列里面取出数据来显示....................
[/Quote]

这个方式可行!
dirdirdir3 2009-10-14
  • 打赏
  • 举报
回复
线程接收图像并显示..........这样做很不好,线程除非是自带界面的不然最好不要插足显示,不然很容易出问题....................最好的方法是开个线程接收数据,存放于一个加了同步锁的队列里面,然后界面线程从这个队列里面取出数据来显示....................
coder0621 2009-10-14
  • 打赏
  • 举报
回复
问题说的不是很清楚,原因也不好确定,单线程没问题,多线程有问题,那肯定是共享的数据出问题了,检查一下线程间同步,该加锁的地方加锁。

我在多线程排错的时候一般都是打日志,因为跟踪调试的话,线程执行顺序就打乱了,不容易找到,通过打日志把各个共享数据的内容打出来,可以很容易的了解程序运行的细节,而且程序崩溃的位置也能大体确定下来,剩下的应该就很好解决了。

best wish
huofen2005 2009-10-14
  • 打赏
  • 举报
回复
接收图像搞个线程,显示图像搞个线程,图象搞在一个列表缓冲里面。
FIFO,一个塞一个取,取完了就等着,塞满了就丢。
feelang 2009-10-14
  • 打赏
  • 举报
回复
坐等大牛出现

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧