强制线程在睡着时返回

时间:2013-07-13 06:29:24

标签: multithreading c++11 sleep kill

背景

我目前正在使用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());
    }
}

提前感谢您的帮助。

3 个答案:

答案 0 :(得分:0)

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

希望它有所帮助。

答案 1 :(得分:0)

查看Condition variables

而不是“休眠”,线程阻塞条件变量,在发出信号时唤醒。阻塞可能是超时 - 因此如果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如果您有任何问题/评论