[英]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:以下是我对您的需求的理解:
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.