【发布时间】:2012-03-17 16:57:26
【问题描述】:
目前我的程序中有两个线程在运行:
主线程 - 从网络摄像头抓取图像,存储在 CVD 图像中。对此图像进行处理。
服务器线程 - 使用命名管道将存储在上述 CVD 图像中的完整图像数据发送到其客户端。
当我运行我的程序时,它会运行很短的时间,然后崩溃并出现以下异常:
0xC000005: Access violation reading location 0x0000000
我认为这是因为我的服务器线程正试图与主线程同时访问图像。
我之前没有做过任何并发编程(这是我第一次),但我现在对如何解决它有一个模糊的想法。
我的计划是在服务器准备将图像发送给客户端时设置某种锁,以防止从主线程访问图像。但是我意识到可能存在一个问题,即服务器线程不断地保留资源,因为客户端不断地请求一个新的帧。所以我想只在从网络摄像头抓取新帧时才响应客户端,以避免上述阻塞问题。
总结一下:
主线程:
1. If Image is available
then - Lock image, copy over new data from webcam, release image
else - goto 1
2. Do processing
服务器:
1. Receive request for new frame from client
2. If (haven't sent the current frame yet)
then - Lock CVD image access, send over frame, release image.
else - wait until new image available.
3. goto 1
我的问题是,这会是一个合适的解决方案吗?为了实现这一点,我需要什么?即如何在另一个线程正在执行其自己的代码的一部分时停止执行我的代码的某些部分。
更多信息:
- 我用的是VS2010 C++
- 客户端是C#,只有1个客户端。
- 我正在使用 image[x][y] 从 CVD 图像中访问图像数据,它返回一个表示图像强度的字节值。
- 有一个可用于 CVD 图像的 copyTo() 函数。它似乎对图像进行内存复制以创建具有相同数据的新对象。这有用吗?
- 我无法在调试模式下运行程序,因为我正在处理未设置调试模式的现有代码库。
【问题讨论】:
-
好像你回答了你自己的问题。是的,锁定是绝对跨线程共享资源的必要条件。您可能想阅读互斥锁和信号量。通常,在我使用的大多数线程库中,库将负责使用系统调用停止“执行 [你的] 代码的某些部分”,直到资源被释放,当然如果做得正确的话。
-
你想对流量控制做什么?通常,网络摄像头和客户端将以不同的速率生成/使用数据。您应该指定当输入的图像数量超过客户端可以使用的数量以及客户端要求提供图像但还没有准备好的图像时要执行的操作。
-
如果有更多的图像进入客户端可以使用,客户端将在请求时简单地获取最新的帧。它是否在调用之间丢帧并不重要。如果客户端请求一个图像并且新图像还没有准备好,它会阻塞直到一个可用(即服务器检测到新图像并通过管道将其发送到客户端)。
标签: c++ image concurrency locking ipc