线程共享资源 C++
Posted
技术标签:
【中文标题】线程共享资源 C++【英文标题】:Threads sharing resources C++ 【发布时间】: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() 函数。它似乎对图像进行内存复制以创建具有相同数据的新对象。这有用吗?
我无法在调试模式下运行程序,因为我正在处理未设置调试模式的现有代码库。
【问题讨论】:
好像你回答了你自己的问题。是的,锁定是绝对跨线程共享资源的必要条件。您可能想阅读互斥锁和信号量。通常,在我使用的大多数线程库中,库将负责使用系统调用停止“执行 [你的] 代码的某些部分”,直到资源被释放,当然如果做得正确的话。 你想对流量控制做什么?通常,网络摄像头和客户端将以不同的速率生成/使用数据。您应该指定当输入的图像数量超过客户端可以使用的数量以及客户端要求提供图像但还没有准备好的图像时要执行的操作。 如果有更多的图像进入客户端可以使用,客户端将在请求时简单地获取最新的帧。它是否在调用之间丢帧并不重要。如果客户端请求一个图像并且新图像还没有准备好,它会阻塞直到一个可用(即服务器检测到新图像并通过管道将其发送到客户端)。 【参考方案1】:假设您不想丢帧,我会使用一个循环缓冲区,这样我就可以在读取一帧的同时向客户端写入不同的帧。
查看http://msdn.microsoft.com/en-us/library/windows/desktop/ms682530(v=vs.85).aspx 了解有关 Windows 关键部分的信息。
最后,如果您有现有代码,为什么不能打开调试信息并重新构建?否则,您将在黑暗中射击,试图找出这次崩溃的原因。
【讨论】:
我实现了临界区和循环缓冲区,效果很好。谢谢:)【参考方案2】:当另一个线程正在执行它自己的代码的一部分时,我如何停止执行我的代码的某些部分
同步将由管道本身完成 - 如果您在客户端调用 ReadFile()
¹,它将暂停执行,直到有数据通过它。
MSDN 上有管道server 和client 的示例实现。这可能会有所帮助。
¹我的意思是不重叠呼叫
【讨论】:
问题不在于管道逻辑本身。发送过来的字节数组不是共享资源,它是在调用 WriteFile() 将图像发送到客户端之前在服务器线程中创建的 CVD 图像数据的副本。 @Jkh2 据我了解,您需要一种同步多个线程的方法。我对么?如果是这样,那么您可以使用简单的互斥锁来保护共享资源。正如 user80222 的回答中提到的,关键部分可能适合您的需求。以上是关于线程共享资源 C++的主要内容,如果未能解决你的问题,请参考以下文章