Multithreading 强制线程在睡眠时返回 背景
我目前正在使用C++11为raspberry pi开发一个程序。基本设计(与此问题相关)为:Multithreading 强制线程在睡眠时返回 背景,multithreading,c++11,sleep,kill,Multithreading,C++11,Sleep,Kill,我目前正在使用C++11为raspberry pi开发一个程序。基本设计(与此问题相关)为: 我有一个主循环,它正在等待来自外部源的命令 在主循环中,我创建了一个代理(在单独线程中运行的对象),该代理将一直休眠,直到有东西添加到其队列中,在这种情况下,它将唤醒并处理该项,然后在返回休眠之前再次检查队列中是否有任何项(如果有更多项要处理,则重复此过程) 在项目的“处理”过程中,我只是在X秒内一次启用/禁用一个GPIO引脚 处理伪代码: for (Pin pin : pins) { se
- 我有一个主循环,它正在等待来自外部源的命令
- 在主循环中,我创建了一个代理(在单独线程中运行的对象),该代理将一直休眠,直到有东西添加到其队列中,在这种情况下,它将唤醒并处理该项,然后在返回休眠之前再次检查队列中是否有任何项(如果有更多项要处理,则重复此过程)
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%的时间将用于睡眠(它执行代码的唯一时间是在设置pin输出时(此处不涉及数据)
问题:
我应该如何从主线程取消当前项目的处理?我不想终止线程,我只是希望它返回到它的运行循环来处理队列中的下一个项目(或返回睡眠)
我可以想办法做到这一点,我只是想听听社区的一些想法,并选择最好的解决方案
附加代码
这个类在单独的线程中运行,处理队列中的项目。
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());
}
}
#包括“ScheduleThread.h”
ScheduleThread::ScheduleThread()
:thread(&ScheduleThread::run,this)
{
}
ScheduleThread::~ScheduleThread(){
//TODO自动生成的析构函数存根
}
void ScheduleThread::QueueSchedule(Schedule*Schedule)
{
锁和防护锁(m);
调度队列推送(调度);
stateChangedSema.post();
}
bool ScheduleThread::scheduler()
{
如果(!schedule_queue.empty())
{
Schedule*Schedule=Schedule_queue.front();
计划->运行计划();
schedule_queue.pop();
返回true;
}
返回false;
}
void ScheduleThread::run()
{
对于(;;)
{
stateChangedSema.wait();
while(scheduler());
}
}
提前感谢您的帮助。我不知道我是否理解您的意图,但是如果您想从主线程与某个线程通信,您只需设置一个标志(声明为全局变量)并使线程参考此标志,以便根据需要更改其行为。例如,您可以将此变量添加到保持执行
调度程序()
函数的while
语句中。其他想法可能涉及使用
希望有帮助。调查
线程不会“休眠”,而是阻塞条件变量,并在发出信号时唤醒。阻塞可能是一个超时-因此,如果condvar超时,线程可以做一件事(例如,再次循环),如果condvar发出信号,它可以做其他事情
注意关于虚假醒来的警告
伪ish代码可能是:
// 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);
还是我误解了你的意思?嗨,我有一个例子可以帮助你理解条件变量是如何工作的。 您可以声明两个线程(两个无限循环)
- 一个接收用户输入并向另一个线程发出信号,表明一个输入已准备好进行处理的线程
- 另一个处理它并发出信号说他已经完成了
#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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
//这将模拟用户的任何操作(例如,将其用于pin)
int GetUserName()
{
while(true)
{
coutUnrelated red flag:您在QueueSchedule
中使用mutexm
来保护schedule\u queue
,但在scheduler
中没有。我的数据竞争感觉很刺痛。如果schedule\u queue
是单生产者单消费者队列,并且您正在使用mutex来同步多个生产者,那么我的数据竞争-sense是错误的,需要修复。