c++ - 2个并行线程运行,每个线程控制一个设备。我可以用什么来实现它?
问题描述
我的设备是相机。
我希望能够启动线程一,并为该线程中的设备一运行类似于状态机的东西。设备二也一样。
到目前为止,我已经为该设备编写了所有控制功能。我可以在两个不同的线程中完全运行它们。我需要做的是能够从主线程控制它们。
对于我的控制线程,我创建了一个始终为 true 的 while 循环,除非传递了对应于 break 循环的对变量的原子引用。
我想从主线程做的是向线程发送一个命令来捕获一帧。捕获一帧需要 10 毫秒。在捕获第一帧的中途,我想向线程二发送命令以捕获帧并继续这样做。
void classA::Capture(WINUSB_INTERFACE_HANDLE * handle, std::atomic<int>& cap)
{
std::vector<byte> frame;
while (true)
{
if (cap == 1)
{
frame = CaptureFrame(*handle);
cap = 0;
}
else if (cap == 2)
}
}
void ClassA::run()
{
std::vector<WINUSB_INTERFACE_HANDLE> devices = GetHandles();
Initialize(devices[0]);
Initialize(devices[1]);
WINUSB_INTERFACE_HANDLE h1 = devices[0];
WINUSB_INTERFACE_HANDLE h2 = devices[1];
std::atomic<int> cap1{ 0 };
std::atomic<int> cap2{ 0 };
std::thread t1(&ClassA::Capture,this, &h1, &n1, ref(cap1));
std::thread t2(&ClassA::Capture,this, &h2, &n2, ref(cap2));
for (int c = 0; c < 2000; c++)
{
if (c % 2 == 0)
{
cap1 = 1;
Sleep(5);
}
else
{
cap2 = 1;
Sleep(5);
}
}
cap1 = 2;
cap2 = 2;
t1.join();
t2.join();
}
最终发生的是,有时设备以正确的顺序工作并抓取帧,如 121212,但有时设备会跳过并执行此操作 1211221。(1 我的意思是设备 1,2 设备 2,捕获顺序)
环顾四周后,我发现std::queue
但我不确定如何实现它。非常感谢。我很抱歉造成混乱。任何帮助表示赞赏。
解决方案
如果保持帧捕获的“121212”顺序绝对至关重要,那么您将需要比您拥有的更多。特别是,两个捕获线程都需要等待它们 10 毫秒的心跳,但它们还需要确保另一个相机已经捕获了一个帧。
你有这个正确的基础,因为你有正确的线程来完成所涉及的任务,但是这些线程需要更复杂一些。这将是伪代码而不是实际的 C++,但它应该提供一个基础。
您需要四个“事件” - 这些可以使用原始 Win32 事件来完成,或者对于平台无关版本,astd::mutex
和 astd::condition_variable
将完成工作。事件是capture1
capture2
started1
和started2
。 capture
主线程使用事件来触发帧捕获,started
事件通知主线程适当的捕获线程实际上已经开始捕获帧。
主控代码:
// create all four events.
std::thread t1(&ClassA::Capture,this, &h1, &n1, ref(trigger1), ref(started1));
std::thread t2(&ClassA::Capture,this, &h2, &n2, ref(trigger2), ref(started2));
for (int c = 0; c < 2000; c++)
{
PostEvent(trigger1);
WaitForEvent(started1);
Sleep(5);
PostEvent(trigger2);
WaitForEvent(started2);
Sleep(5);
}
然后你的线程循环看起来像这样:
void classA::Capture(WINUSB_INTERFACE_HANDLE * handle, Event& trigger, Event& started)
{
std::vector<byte> frame;
while (true)
{
WaitForEvent(trigger);
PostEvent(started);
// Did you really mean to return the frame as a vector<byte> by value?
// That's not going to perform well, consider passing frame by reference into CaptureFrame()
frame = CaptureFrame(*handle);
}
}
标准免责声明适用:此代码尚未编译,并且可能不会按原样编译:您需要该Event
对象才能使其工作。
推荐阅读
- asp.net-core - Razor 视图不为 Razor 页面生成 href
- windows - Windows 内存保护:VirtualProtect 与 CryptProtectMemory
- java - Viewpager2 和片段
- c - 为什么 C 在处理字符串/字符时在 scanf() 中不需要 '&'
- python - 使用 sudo pip 有多危险?
- javascript - 获取总和为 11 的所有 3 位数字,或者我们可以说模块在 JS 中为 1
- php - 根据 PHP 条件将类应用于两个元素
- reactjs - React - 在渲染时激活声音
- c++ - 每个函数结束时是否需要返回?
- api - 如何管理从 Micronaut 客户端到 REST API 的 JWT 登录过程?