暂停并恢复c++函数

Pause and resume a c++ function

本文关键字:函数 c++ 恢复 暂停      更新时间:2023-10-16

我在编程中遇到了一个问题,我没有找到任何方便快捷的执行解决方案。

我正在尝试实现某种状态机:在条目中取一个字节,处理它,更改状态,循环等等。目的是处理字节流,而不需要任何内存缓冲区(处理每个字节的字节)。

类应该是这样的:

class Decoder {
void next() {
int i = 0;
std::cout << i << "n";
i++;
yield(); // pseudo code => should stop the function and save the current state (or simply not freeing allocated variables)
std::cout << i << "n";
}
};
Decoder decoder = Decoder();
decoder.next(); // print 1
std::cout << "1.5" << "n"; // print 1.5
decoder.next(); // print 2

一个解决方案可以是创建一个step属性来保存步骤,然后使用开关恢复,但性能会受到严重影响。我想知道是否有一种方法可以退出函数的执行,然后再继续执行?

需要明确的是,我不想暂停整个程序,只想暂停一个函数。暂停这样的函数将返回调用方并继续执行程序,直到调用下一个next为止。

此外,我希望尽量避免线程和std(我更喜欢所有环境代码)。最后,如果您对我的问题有任何其他选择:有效地处理内存的字节流,我愿意接受您的建议。

谢谢你的帮助。

我相信您可以通过以下两种方式实现这一点:

选项1:成员国

将状态机对象拆分为一个单独的对象,并将所有本地变量转换为成员。

对于每一步,都要保存一个State成员,表示您在整个程序执行过程中所处的位置。

每次输入next()时,请对照开关检查您的状态,并为该步骤调用指定的内部方法。

每个这样的步骤方法模拟到连续CCD_ 5之间的代码执行。

struct Decoder {
void next() {
switch (_step) {
case s1:
step1();
_step = s2;
return;
case s2:
step2();
_step = s1;
return;
default:
return; // handle error...
}
}
private:
enum Step { s1, s2 };
Step _step = s1;
int _i = 1;
void step1() {
std::cout << _i << "n";
_i++;
}
void step2() {
std::cout << _i << "n";
}
};
int main() {
Decoder decoder = Decoder();
decoder.next(); // print 1
std::cout << "1.5" << "n"; // print 1.5
decoder.next(); // print 2
}

选项2:线程和信号

使用线程,当然可以使用本机API(例如,在POSIX平台上的pthread_create)运行该线程。

在线程中,每次想要yield时,都要等待一个条件变量,例如:

struct Decoder {
Decoder() {
_thread = std::thread { &Decoder::worker, this };
}
~Decoder() {
_thread.join();
}
void next() {
std::lock_guard<std::mutex> lock(_mutex);
_work = true;
}
private:
void wait() {
std::unique_lock<std::mutex> lock(_mutex);
_cond.wait(lock, [this](){return _work;});
}
void worker() {
wait();
int i = 0;
std::cout << i << "n";
i++;
wait();
std::cout << i << "n";  
}
std::thread _thread;
std::mutex _mutex;
std::condition_variable _cond;
bool _work = false;
};
int main() {
Decoder decoder;
decoder.next(); // print 1
std::cout << "1.5" << "n"; // print 1.5
decoder.next(); // print 2
}