我目前正在使用C ++ 11为raspberry pi开发一个程序。基本设计(与此问题相关)是:
在项目的“处理”中,我只是一次启用/禁用GPIO引脚一次,持续X秒。
处理伪代码:
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)
是对上述伪代码描述的函数的调用。
ScheduleThread.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());
}
}
提前感谢您的帮助。
答案 0 :(得分:0)
我不知道我是否理解你正在尝试做什么,但是如果你想与主线程中的某个线程进行通信,你可以简单地设置一个标志(声明为全局变量)并制作线程咨询此标志,以便根据需要更改其行为。例如,您可以将此变量添加到继续执行while
函数的scheduler()
语句中。其他想法可能涉及使用condition variables。
希望它有所帮助。
答案 1 :(得分: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);
或者我误解了你的目标?
答案 2 :(得分: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;
}
如果您有任何疑问,请告诉我,o如果您有任何问题/评论