0

背景

我目前正在为树莓派开发一个使用 C++11 的程序。基本设计(与这个问题相关)是:

  • 我有一个等待来自外部源的命令的主循环。
  • 在主循环中,我创建了一个代理(在单独的线程中运行的对象),它一直处于休眠状态,直到将某些内容添加到其队列中,在这种情况下,它会唤醒,处理该项目,然后再次检查队列中是否有任何项目重新进入睡眠状态(如果还有更多需要处理,则重复此过程)

在该项目的“处理”中,我只是在 X 秒内一次启用/禁用一个 GPIO 引脚。

处理伪代码:

for (Pin pin : pins)
{
    set_pin(pin, HIGH);
    this_thread::sleep_for(chrono::seconds(x))
    set_pin(pin, LOW);
    this_thread::sleep_for(chrono::seconds(y))
}

显然,该线程 99.999% 的时间都将用于睡眠(它执行代码的唯一时间是设置引脚输出时(此处未触及数据)

问题

我应该如何从主线程取消当前项目的处理?我不想杀死线程,我只想让它返回到它的运行循环以处理队列中的下一个项目(或回到睡眠状态)。

我可以想办法做到这一点,我只是想听听社区的一些想法并选择最佳解决方案。

附加代码

这是在单独线程中运行的类,用于处理队列中的项目。 schedule->RunSchedule(schedule)是对上面伪代码描述的函数的调用。

调度线程.cpp

#include "ScheduleThread.h"

ScheduleThread::ScheduleThread()
    : thread(&ScheduleThread::run, this)
{
}

ScheduleThread::~ScheduleThread() {
    // TODO Auto-generated destructor stub
}

void ScheduleThread::QueueSchedule(Schedule *schedule)
{
    lock_guard<mutex> lock(m);
    schedule_queue.push(schedule);
    stateChangedSema.post();
}

bool ScheduleThread::scheduler()
{
    if (!schedule_queue.empty())
    {
        Schedule *schedule = schedule_queue.front();
        schedule->RunSchedule();
        schedule_queue.pop();
        return true;
    }
    return false;
}

void ScheduleThread::run()
{
    for(;;)
    {
        stateChangedSema.wait();
        while (scheduler());
    }
}

提前感谢您的帮助。

4

3 回答 3

0

查看条件变量

线程不是“休眠”,而是在条件变量上阻塞,在收到信号时唤醒。阻塞可能是超时——所以如果 condvar 超时,线程可以做一件事(例如再次循环循环),如果 condvar 发出信号,它可以做其他事情。

注意关于虚假唤醒的wait_for警告。

伪代码可能是:

// assumes the condvar is triggered when cancellation is reqd.

if(condvar.wait_for( lock, std::chrono::seconds( x ) ) != std::cv_status::timeout)
    return;
set_pin(pin, HIGH);
if(condvar.wait_for( lock, std::chrono::seconds( y ) ) != std::cv_status::timeout)
    return;
set_pin(pin, LOW);

还是我误解了你的目的?

于 2013-07-15T15:10:44.930 回答
0

我不知道我是否理解你想要做什么,但如果你想从主线程与某个线程通信,你可以简单地设置一个标志(声明为全局变量)并让线程咨询这个标记,以便根据需要改变他们的行为。例如,您可以将此变量添加到while继续执行您的scheduler()函数的语句中。其他想法可能涉及使用条件变量

希望能帮助到你。

于 2013-07-13T17:16:11.440 回答
0

嗨,我有一个示例可以帮助您了解条件变量的工作原理。您声明两个线程(两个无限循环)。

  • 一个接受用户输入并向另一个线程发出信号,表明一个输入已准备好进行处理
  • 另一个处理它并发出他已经完成的信号

这是代码

#include <thread>
#include <chrono>
#include <mutex>
#include <iostream>
#include <string>
#include <condition_variable>
#include <atomic>
using namespace std;

//this simulates any action from the user (use it for your pin for example)
int GetUserName()
{
    while (true)
    {
        cout<<"Enter your name " << endl;
        cin>> UserName;
        NewName=true;//one new name is ready to be processed
        cv.notify_one();

        // Wait until the naame has been processed
        {
            std::unique_lock<std::mutex> lk(m);
            cv.wait(lk, []{return (NewName==false);});
        }   
    }
    return 0;
}

//this reacts to any action of the user, processes the data and signals that he's done
int ProcessName()
{
    while (true)
    {
            //waiting for one data to be processed
        {
            std::unique_lock<std::mutex> lk(m);
            cv.wait(lk, []{return (NewName==true);});
        }
        cout<<"Hey "+UserName<<"!"<<endl;
        NewName=false;//sets to flase because the data are processed
        cv.notify_one();//I have processed the data, the user can input something else
    }
    return 0;
}

告诉我这是否有帮助,或者如果您有任何问题/意见

于 2013-08-20T20:22:33.190 回答