再会,
好吧,我知道已经有一些关于 Boost.Fiber 和 Goroutines 比较的讨论。但是作为并发领域的新开发人员,我对差异和可用性感到很困惑。
所以目前,我正在做一些 Go 到 C++ 的迁移,我的一些障碍是使用 Channels 和 Goroutines,所以我对并发、Boost.Fiber 和 Goroutines 做了一些小阅读,并根据我的理解做了一个示例实现关于这个话题。
package main
import (
"fmt"
"time"
)
const (
timeout = 0
interrupt = 1
serverDone = 2
)
func runDurationTimer(d time.Duration, toStop chan int) {
go func() {
dSeconds := uint64(d.Seconds())
if dSeconds == 0 {
return
}
time.Sleep(d)
toStop <- timeout
}()
}
func clientWatchControlChannel(d time.Duration, toStop chan int) {
go func() {
time.Sleep(d)
toStop <- serverDone
}()
}
func main() {
toStop := make(chan int, 1)
d := 5 * time.Second
runDurationTimer(d, toStop)
clientWatchControlChannel(1 * time.Second, toStop)
fmt.Println("Hello World \n")
reason := <-toStop
switch reason {
case timeout:
fmt.Println("Process done, duration: " + d.String() +".")
case interrupt:
fmt.Println("Process done, received interrupt signal.")
case serverDone:
fmt.Println("Process done, server terminated the session.")
}
}
所以上面的代码是一个基本的成功和超时方案,当一个函数在一定时间内没有返回一个状态时,它就会超时。
在clientWatchControlChannel
实际场景中,这Sleep
将是需要返回某些内容并完成该过程的其他进程。基于硬编码值,整个程序返回"Process done, server terminated the session."
,因为运行的持续时间clientWatchControlChannel
< 中的超时值runDurationTimer
。
toStop <- timeout
因此,当我调试代码时,它会运行 2 个过程,因此我在and处放置了一个断点toStop <- serverDone
,因此runDurationTimer
运行然后休眠,然后在等待完成时运行clientWatchControlChannel
然后首先完成,因为它的持续时间小于runDurationTimer
,在此之后,它不会去返回runDurationTimer
并等待,它只是终止并为输出分配值。
根据我对 C++ 的理解,我编写了以下代码。
#include <boost/fiber/all.hpp>
#include <chrono>
#include <iostream>
typedef boost::fibers::unbuffered_channel<int> unbuffered_channel_t;
enum stop { timeout = 0, interrupt, serverDone };
void runDurationTimer(
const std::chrono::duration<std::uint32_t, std::ratio<1, 1>> &d,
unbuffered_channel_t &toStop) {
boost::fibers::async([&]() {
if (d.count() == 0) {
return;
}
boost::this_fiber::sleep_for(d);
toStop.push(timeout);
});
}
void clientWatchChannel(
const std::chrono::duration<std::uint32_t, std::ratio<1, 1>> &d,
unbuffered_channel_t &toStop) {
boost::fibers::async([&]() {
boost::this_fiber::sleep_for(d);
toStop.push(serverDone);
});
}
int main() {
unbuffered_channel_t chan;
auto dTime = std::chrono::duration<std::uint32_t, std::ratio<1, 1>>(3);
auto dWatch = std::chrono::duration<std::uint32_t, std::ratio<1, 1>>(1);
runDurationTimer(dTime, chan);
clientWatchChannel(dWatch, chan);
std::cout << "Hello, World!\n";
int i = 0;
chan.pop(i);
switch (i) {
case timeout:
std::cout << "Process done, duration: " << std::to_string(dTime.count())
<< ".";
break;
case interrupt:
std::cout << "Process done, received interrupt signal.";
break;
case serverDone:
std::cout << "Process done, server terminated the session.";
break;
default:
break;
}
return 0;
}
所以长话短说,一切在行为上几乎是一样的。再次,我调试了代码,在toStop.push(serverDone);
and中放置了断点toStop.push(timeout);
,所以与 Go 相同,它runDurationTimer
先运行然后等待它完成clientWatchControlChannel
并运行toStop.push(serverDone);
,但不同之处在于它不是终止,而是返回runDurationTimer
并运行toStop.push(timeout);
。所以我认为这是我真正感到困惑的事情。然后chan.pop(i)
返回serverDone
。
所以,我真的需要一些帮助来理解它是否正确,或者我应该继续使用 Boost.Fiber 进行 Go 迁移还是使用 Boost.Coroutines2。感谢任何建议,反应和更正,我愿意从中学习。
我也对我的 C++ 表示歉意,一直停滞不前。:)
谢谢。