我的设备是相机。
我希望能够启动一个线程,并在该线程中为一个设备运行类似于状态机的内容。 第二个设备也是如此。
到目前为止,我已经为设备编写了所有控制功能。我可以在两个完全不同的线程中运行它们。我需要做的是能够从主线程控制它们。
对于我的控制线程,我创建了一个while循环,除非传递了对与break循环相对应的变量的原子引用,否则它始终为true。
我要从主线程执行的操作是向一个线程发送一条命令,说要捕获一个帧。捕获帧需要10毫秒。在捕获第一个帧的一半过程中,我想向线程2 发送命令以捕获一个帧并继续这样做。
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,捕获顺序)< / p>
环顾四周后,我发现了std::queue
,但不确定如何实现。非常感谢你。对不起,我感到困惑。任何帮助表示赞赏。
答案 0 :(得分:1)
两个线程之间可能有一个race condition。一个线程中的CaptureFrame在第二个线程中被调用之前没有完成。
如果顺序很重要,那么为什么要有两个线程?为什么没有一个仅重复调用CaptureFrame的线程?
如果您确实需要两个线程,请签出std :: mutex。您可以同步两个线程,以便在任何时候只有一个处于活动状态。
如果您需要一个线程在另一个线程仍处于活动状态时启动,那么请检出nanosleep(对于Linux)或similar(对于Windows)。定期睡眠对于您的用例而言是不精确的。
答案 1 :(得分:1)
如果保持帧捕获的“ 121212”顺序绝对至关重要,那么您将需要的比您需要的更多。特别是,两个捕获线程都需要等待10毫秒的心跳,但是还需要确保另一个摄像机捕获了一个帧。
您拥有正确的基础,因为您拥有正确的线程来执行所涉及的任务,但是这些线程将需要更加复杂。这将是伪代码,而不是实际的C ++,但它应该提供基础。
您需要四个“事件”-可以使用原始Win32 EVENT完成,或者对于平台无关的版本,std::mutex
和std::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
对象才能使其正常工作。