简体   繁体   English

C++ 线程:从主线程触发循环

[英]C++ Threads : Trigger a loop from main thread

I have 4 sensors that I would like to poll asynchronously inside 4 different threads.我有 4 个传感器,我想在 4 个不同的线程中异步轮询它们。 I have a timer that will call a function at 30Hz and I would like this function to trigger the polling inside the threads.我有一个计时器,它将以 30Hz 的频率调用 function,我希望这个 function 触发线程内的轮询。

I have tried using std::async to spawn 4 threads each time the timer calls but the overhead of creating the threads is too much.我尝试使用std::async每次定时器调用时产生 4 个线程,但创建线程的开销太大。 Here is what I did with std::async :这是我对std::async所做的:

for (auto& camera : camera_vector_) {
  camera_asyncs_.emplace_back(
      std::async(std::launch::async, [camera]() -> bool {
          return camera->poll();
      })
  );
}

for (auto& future : camera_asyncs_) {
  future.get();
}


Now I need my 4 threads to be spawned at the start of the program and wait for the clock to tell them to unlock and run the process function.现在我需要在程序开始时生成 4 个线程并等待时钟告诉它们解锁并运行进程 function。 something like this:像这样的东西:

for (auto& camera : camera_vector_)
{
  camera_threads_.emplace_back(std::thread([&camera]() {
    while (true)
    {
      wait_for_trigger();
      camera->poll();
      block_trigger();
    }
  }));
}

void Driver::poll_threads() {
  for (auto& thread : camera_threads_) {
    trigger_thread(thread);
  }
}

How would you do this?你会怎么做? my research led me to mutexes, and condition variables.我的研究使我想到了互斥体和条件变量。 For example here .例如这里 But the examples I found were to start a bunch of threads and let them finish.但是我发现的例子是启动一堆线程并让它们完成。 not to trigger one loop in one thread at a time.不要一次在一个线程中触发一个循环。

Also it seems that what I need here is not a thread pool, because each thread as a defined job that just need a trigger.此外,似乎我在这里需要的不是线程池,因为每个线程都是一个定义的作业,只需要一个触发器。 Am I correct?我对么?

It seems to me that using mutexes is the right thing to do.在我看来,使用互斥锁是正确的做法。 Should I store them in a second vector the same size as my thread vector?我应该将它们存储在与我的线程向量相同大小的第二个向量中吗? I know I can lock a mutex inside the thread, but can I unlock the mutex from the main thread?我知道我可以在线程内锁定互斥锁,但我可以从主线程解锁互斥锁吗? Do you have any tips for implementing this?你有什么实现这一点的技巧吗?

I am using C++14.我正在使用 C++14。

Thanks for your help.谢谢你的帮助。

Here is my understanding about your need:以下是我对您的需求的理解:

  1. You just need four threads, no more no less;你只需要四个线程,不多不少;
  2. The four threads are independent each other, meaning that they don't share data;四个线程相互独立,不共享数据;
  3. Each thread is triggered and do job every 33ms, in one 33ms, it can't do job more than once;每个线程每 33ms 触发一次工作,一个 33ms 内不能多次工作;
  4. If a thread is still working on the last job while the trigger happening, the thread is allowed to ignore this trigger.如果触发发生时线程仍在处理最后一个作业,则允许线程忽略此触发。

I will do the design as below:我会做如下设计:

#include <thread>
#include <vector>
#include <chrono>
#include <iostream>
#include <atomic>

using namespace std;

std::atomic_flag lock0 = ATOMIC_FLAG_INIT;
std::atomic_flag lock1 = ATOMIC_FLAG_INIT;
std::atomic_flag lock2 = ATOMIC_FLAG_INIT;
std::atomic_flag lock3 = ATOMIC_FLAG_INIT;

void trigger() {
    while (true) {
        lock0.clear(); // set to false
        lock1.clear(); // set to false
        lock2.clear(); // set to false
        lock3.clear(); // set to false
        std::this_thread::sleep_for(std::chrono::milliseconds(33)); // 33 ms = 1000ms/30
        // from now on, all threads lost the chance to be triggered
        // they have to wait for the next time
        lock0.test_and_set(); // set to true
        lock1.test_and_set(); // set to true
        lock2.test_and_set(); // set to true
        lock3.test_and_set(); // set to true
    }
}

void f0()
{
    while (true) {
        while(!lock0.test_and_set()) {
            std::cout << "f0" << std::endl;
        }
    }
}

void f1()
{
    while (true) {
        while(!lock1.test_and_set()) {
            std::cout << "f1" << std::endl;
        }
    }
}

void f2()
{
    while (true) {
        while(!lock2.test_and_set()) {
            std::cout << "f2" << std::endl;
        }
    }
}

void f3()
{
    while (true) {
        while(!lock3.test_and_set()) {
            std::cout << "f3" << std::endl;
        }
    }
}

int main()
{
    std::vector<std::thread> v; // use std::async if you want
    std::thread t(trigger);
    v.emplace_back(f0);
    v.emplace_back(f1);
    v.emplace_back(f2);
    v.emplace_back(f3);
    for (auto &ele : v) {
        ele.join();
    }
    t.join();

    return 0;
}

This code won't block, instead, it would keep running and do nothing untill the trigger comes.这段代码不会阻塞,相反,它会继续运行并且什么都不做,直到触发到来。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM