这必须在定时器运行优先处理方法定时器、方法

2023-09-11 02:33:23 作者:勾勒出一抹最完美的骄傲つ

这个问题不是任何特定的语言,这是相当解决问题。

This question is not about any specific language, it's rather solving a problem.

我有发送方法的机器人,并要求对传感器数据的定时器。

I have a timer that sends a method to a robot and asks for sensor data.

有些传感器是真正的关键,应该总是被要求,而另一些传感器并不重要,但应及时读取时间。

Some sensors are really critical and should be almost always be requested while some other sensors are not that critical but should be read from time to time.

所以,想象一下,我有我的定时器和定时器它要求将通过下面的code返回的方法:

So imagine I have my timer and in the timer it asks for a method that will be returned by the code below:

Timer_Tick()
{
   AskForData(SensorRequestList())
}

private int _tCliffState = 0;
private int _tCliffSignal = 0;
private int _tLight = 0;
//and 7 other 

private byte[] SensorRequestList()
{
    if (_tCliffState <= 5)
    {
        _tCliffState++;
        return RequestCliffStates();
    }
    if(_tCliffSignal < 1)
    {
        _tCliffSignal++;
        return RequestCliffSignals();
    }
    if(_tLight < 1)
    {
        _tLight++;
        RequestLightSignals();
    }
    //and more ifs!


    //reset all
    _tCliffState = 0;
    _tCliffSignal = 0;
    _tLight = 0;
    //...
}

什么是最好的方式,如果我有10个方法,让说,命名为喜欢1,2,3,... 10,也是当务之急是像1,2,3 ...... 10。

What is the best way if I have 10 methods, lets say named like 1,2,3,...10 and also priority is like 1,2,3...10.

我如何achive一个很好的模式,我可以肯定的是更优先的方法将要求更多吗?这样的模式:

How can I achive a nice pattern that I can be sure that methods with more priority will requested more? something like this pattern:

1,1,1,2,1,3,1,1,4,1,1,1,2,1,1,1,3,1,1,1,4等等

推荐答案

这样的你正在使用的一个计数器技术的问题是,在给定的时间,你可能有一个以上的方法的资格执行。在解决方案来缓解这个问题是停止计数,队列中的所有合格的方法的,并选择每个排队一个用于下一个计时器事件,直到队列为空。一旦空的,你可以重新开始计数过程中选择一组新的方法的。

The problem with counter techniques like the one you are using is that at a given time you may have more than one method eligible for execution. On solution to mitigate the problem is to stop the counter, queue all the qualified methods, and select each queued one for the next timer events, until the queue is empty. Once empty, you can restart the counting process to select a new set of methods.

下面是一个可能实现(未经测试code),使用 INT 存储的方法的队列:

Here is a possible implementation (untested code), using an int to store the methods queue:

Timer_Tick() {
   AskForData(SensorRequestList());
}

private int _state[NUM_METHODS]; // initialized to 0
private int _priority[NUM_METHODS]; 
private int _flags; // initialized to 0
private (byte [])(*_methods)[NUM_METHODS]; // array of pointer to functions, 
                                                                            // runnables, etc.


private byte[] SensorRequestList() {
     do {
        for (int i = 0; i < NUM_METHODS; ++i)
            if ((1 << i) & _flags){
                _flags &= ~(1 << i);
                _state[i] = 0;
                return _method[i]();
           }

         for (i = 0; i < NUM_METHODS; ++i){
            _state[i]++;
            _flags |= (_state[i] >= _priority[i]) << i;
        }
    } while (!_flags);
}

该实现需要的的方法数的比的sizeof(int)的* 8 平台(假设每个字节8位)更小。它可以很容易地切换到使用一个真实队列为一个大值。

This implementation requires the number of methods to be smaller than sizeof(int) * 8 of the platform (assuming 8bit per byte). It could be easily switched to using a real queue for a larger number.

或者以 _state 重置为 0 ,可以使用如下:

Alternatively to the resetting of _state to 0, one could use the following:

  _state[i] -= _priority[i];

和保持计数器滚动,但这肯定需要如何被选中的单元排队更加小心。

and keep the counters rolling, but this would certainly require much more care in how selected elements are queued.