Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 2个并行线程运行,每个线程控制一个设备。我可以用什么来实现这一点?_C++_Multithreading - Fatal编程技术网

C++ 2个并行线程运行,每个线程控制一个设备。我可以用什么来实现这一点?

C++ 2个并行线程运行,每个线程控制一个设备。我可以用什么来实现这一点?,c++,multithreading,C++,Multithreading,我的设备是照相机 我希望能够启动线程一,并在该线程中运行类似于设备一的状态机。设备二的情况也一样 到目前为止,我已经为该设备编写了所有的控制功能。我可以在两个不同的线程中运行它们。我需要做的是能够从主线程控制它们 对于我的控制线程,我创建了一个while循环,该循环始终为true,除非传递了对应于break循环的变量的原子引用 我想从主线程执行的是向线程一发送一个命令,表示要捕获一帧。捕获一帧需要10毫秒。在捕获第一帧的中途,我想向线程二发送一个命令,以捕获一帧并继续这样做 void class

我的设备是照相机

我希望能够启动线程一,并在该线程中运行类似于设备一的状态机。设备二的情况也一样

到目前为止,我已经为该设备编写了所有的控制功能。我可以在两个不同的线程中运行它们。我需要做的是能够从主线程控制它们

对于我的控制线程,我创建了一个while循环,该循环始终为true,除非传递了对应于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();

}
void classA::Capture(WINUSB_接口_句柄*HANDLE,std::atomic&cap)
{
std::向量帧;
while(true)
{
如果(上限==1)
{
帧=捕获帧(*句柄);
上限=0;
}
否则如果(上限==2)
}
}
void ClassA::run()
{
std::vector devices=GetHandles();
初始化(设备[0]);
初始化(设备[1]);
WINUSB_接口_句柄h1=设备[0];
WINUSB_接口_句柄h2=设备[1];
std::原子cap1{0};
std::原子cap2{0};
std::线程t1(&ClassA::Capture,this,&h1,&n1,ref(cap1));
std::线程t2(&ClassA::Capture,this,&h2,&n2,ref(cap2));
对于(int c=0;c<2000;c++)
{
如果(c%2==0)
{
cap1=1;
睡眠(5);
}
其他的
{
cap2=1;
睡眠(5);
}
}
cap1=2;
cap2=2;
t1.join();
t2.连接();
}
最终发生的是,有时设备按正确的顺序工作并抓取帧,如121212,但有时设备会跳过并执行1211221。(我所说的1是指设备1,2设备2,捕获顺序)

环顾四周后,我发现了
std::queue
,但我不确定如何实现它。非常感谢你。很抱歉给您带来了混乱。感谢您的帮助

这两个线程之间可能存在冲突。一个线程中的CaptureFrame在第二个线程中被调用之前未完成

如果顺序很重要,那么为什么有两个线程?为什么不让一个线程重复调用CaptureFrame呢

如果您确实需要两个线程,那么签出std::mutex。您可以同步这两个线程,以便在任何时候只有一个线程处于活动状态

如果您需要一个线程在另一个线程仍处于活动状态时启动,请检查Linux或Windows。有规律的睡眠对于您的用例来说是不精确的

这两个线程之间可能存在冲突。一个线程中的CaptureFrame在第二个线程中被调用之前未完成

如果顺序很重要,那么为什么有两个线程?为什么不让一个线程重复调用CaptureFrame呢

如果您确实需要两个线程,那么签出std::mutex。您可以同步这两个线程,以便在任何时候只有一个线程处于活动状态


如果您需要一个线程在另一个线程仍处于活动状态时启动,请检查Linux或Windows。有规律的睡眠对于您的用例来说是不精确的

如果保持帧捕获的“121212”顺序是绝对重要的,那么您将需要更多。特别是,两个捕获线程都需要等待10毫秒的心跳,但它们还需要确保另一个摄像头捕获了一帧

你有这个正确的基础,因为你有正确的线程来完成所涉及的任务,但是这些线程需要更复杂一些。这将是伪代码而不是实际C++,但是它应该提供一个基础。 您需要四个“事件”-这些可以使用原始Win32事件来完成,或者对于平台无关的版本,一个
std::mutex
和一个
std::condition_变量将完成任务。事件为
capture1
capture2
started1
started2
<代码>捕获
事件由主线程用于触发帧捕获,
已启动
事件通知主线程相应的捕获线程已实际开始捕获帧

主控制代码:

// 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);
}
//创建所有四个事件。
std::线程t1(&ClassA::Capture,this,&h1,&n1,ref(trigger1),ref(started1));
std::线程t2(&ClassA::Capture,this,&h2,&n2,ref(trigger2),ref(started2));
对于(int c=0;c<2000;c++)
{
事件后(触发器1);
WaitForEvent(已启动1);
睡眠(5);
事件后(触发器2);
WaitForEvent(已启动2);
睡眠(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);
    }
}
void classA::捕获(WINUSB_接口_句柄*句柄、事件和触发器、事件和启动)
{
std::向量帧;
while(true)
{
等待事件(触发器);
事件后(已启动);
//你真的想通过值将帧作为向量返回吗?
//这不太好,请考虑按引用传递给CAPTCION框架()。
帧=捕获帧(*句柄);
}
}

标准免责声明适用:此代码尚未编译,可能不会按原样编译:您需要
事件
对象使其工作。

如果维护帧捕获的“121212”顺序绝对重要,那么您将需要比您拥有的更多。特别是,两个捕获线程都需要等待10毫秒的心跳,但它们还需要确保另一个摄像头捕获了一帧

您拥有正确的基础,因为您有正确的线程来执行所涉及的任务,但是这些线程将