美好的一天,
嗯,我知道已经有一些关于Boost.Fiber和Goroutines比较的讨论。但是,作为并发领域的新开发人员,我对差异和可用性感到非常困惑。
因此,目前,我正在做一些Go to 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
中的超时值。
因此,当我调试代码时,它将运行2个过程,因此我在toStop <- timeout
和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);
和toStop.push(timeout);
中,所以与Go一样,它先运行runDurationTimer
然后等待它完成clientWatchControlChannel
的启动并运行toStop.push(serverDone);
,但区别不在于终止,而是回到runDurationTimer
并运行toStop.push(timeout);
。所以我认为这是我非常困惑的事情。然后chan.pop(i)
返回了serverDone
。
因此,我确实需要一些帮助,以了解它是否正确,或者我应该继续使用Boost.Fiber进行Go迁移还是使用Boost.Coroutines2。感谢您提出任何建议,反应和更正,我愿意从中学习。
我对C ++的道歉也一直停滞不前。 :)
谢谢。
答案 0 :(得分:0)
您必须关闭频道
#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);
// return value would indicate that the channel was closed
// `timeout` will not be inserted into the channel
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);
toStop.close();
});
}
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;
}
std::cout << "\n";
return 0;
}
你好,世界!
处理完成,服务器终止了会话。