在C++中选择类似于context-select的功能。

huangapple go评论85阅读模式
英文:

context-select like features in C++

问题

想象一种情况,我想调用一个执行一些处理的函数,但是有时间限制。我可以使用context.Contextselect在golang中编写一个函数。我想象的代码如下:

package main

import (
	"context"
	"fmt"
	"time"
)

func longRunning(ctx context.Context, msg string) {
	stop := make(chan bool)
	done := make(chan bool)

	go func() {
		for {
			fmt.Printf("long running calculation %v...", msg)
			select {
			case <-stop:
				fmt.Println("time to stop early!")
				return
			default:
			}
		}
		done <- true
	}()

	select {
	case <-done:
		return
	case <-ctx.Done():
		stop <- true
		return
	}
}

func main() {
	ctx := context.Background()
	ctx, cancel := context.WithTimeout(ctx, 3*time.Second)
	defer cancel()

	longRunning(ctx, "wheeee")
}

在C++中有没有类似的模式可以实现类似的结果?在上面的示例中,select能够以非阻塞的方式监听通道。是否可以使用某种事件文件描述符并监听事件来实现类似的功能?

任何建议或提示将不胜感激。

英文:

Imagine a situation where I'd like to call a function that does some amount of processing, but is time-bound. I could write a function in golang using context.Context and select. I'd imagine something as follows:

package main

import (
	&quot;context&quot;
	&quot;fmt&quot;
	&quot;time&quot;
)

func longRunning(ctx context.Context, msg string) {
	stop := make(chan bool)
	done := make(chan bool)

	go func() {
		for {
			fmt.Printf(&quot;long running calculation %v...&quot;, msg)
			select {
			case &lt;-stop:
				fmt.Println(&quot;time to stop early!&quot;)
				return
			default:
			}
		}
		done &lt;- true
	}()

	select {
	case &lt;-done:
		return
	case &lt;-ctx.Done():
		stop &lt;- true
		return
	}
}

func main() {
	ctx := context.Background()
	ctx, cancel := context.WithTimeout(ctx, 3*time.Second)
	defer cancel()

	longRunning(ctx, &quot;wheeee&quot;)
}

Is there a pattern I can use to achieve similar results in C++? in the sample above select is able to listen on a channel in a non-blocking way. Is having a eventfd file descriptor of some kind and listening to events the way to do it?

Any suggestions or tips would be much appreciated.

答案1

得分: 6

大致如下所示:

void longRunning(std::atomic<bool>& stop) {
  for (;;) {
    if (stop) return;
    // 做一些工作
  }
}

int main() {
  std::atomic<bool> stop = false;
  auto future = std::async(std::launch::async, longRunning, std::ref(stop));
  future.wait_for(std::chrono::seconds(num_seconds));
  stop = true;
  future.get();  // 等待任务完成或提前退出
}

演示

英文:

Something along these lines, perhaps:

void longRunning(std::atomic&lt;bool&gt;&amp; stop) {
  for (;;) {
    if (stop) return;
    // Do a bit of work
  }
}

int main() {
  std::atomic&lt;bool&gt; stop = false;
  auto future = std::async(std::launch::async, longRunning, std::ref(stop));
  future.wait_for(std::chrono::seconds(num_seconds));
  stop = true;
  future.get();  // wait for the task to finish or exit early.
}

Demo

huangapple
  • 本文由 发表于 2021年6月20日 07:25:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/68051489.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定