我正在为我正在写的翻译添加协程支持,我想做类似以下的事情:
typedef enum {
bar_stuff,
bar_other
} Bar;
typedef enum {
foo_error=-1,
foo_none=0,
foo_again
} Foo_state;
Foo_state do_foo(Bar bar,Foo_state foo)
{
switch(foo)
{
case foo_none: //start
switch(bar)
{
case bar_stuff:
//do stuff
return foo_none;
case bar_other:
//do other stuff
return foo_again;
case foo_again: //!! this doesn't work
/* edit: this is supposed to be a case of
* switch(foo), not switch(bar)
*/
//do more other stuff
return foo_none;
default:
//stuff
return foo_none;
}
default:
//fail
return foo_error;
}
}
Run Code Online (Sandbox Code Playgroud)
显然这不起作用(我得到重复的案例值,替代可能是未定义的行为/段错误).我可以将switch(bar)写为if/else …
我正在使用这两个函数来读写大文件(写入多个文件).我想将文件操作保留在函数中,因为这些行可能是从其他源读取/写入的.
更新: C#并没有真正的协程.它是Reactive扩展的一个很好的用例吗?
foreach (var line in ReadFrom("filename"))
{
try
{
.... // Some actions based on the line
var l = .....
WriteTo("generatedFile1", l);
}
catch (Exception e)
{
var l = ..... // get some data from line, e and other objects etc.
WriteTo("generatedFile2", l);
}
}
Run Code Online (Sandbox Code Playgroud)
以下函数打开文件一次,直到读取所有行,然后关闭并释放资源.
private static IEnumerable<string> ReadFrom(string file)
{
string line;
using (var reader = File.OpenText(file))
{
while ((line = reader.ReadLine()) != null)
yield return line;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,以下函数会写入行而不是读取行,为其写入的每一行打开和关闭文件.是否有可能以某种方式实现它,因此它只打开文件一次并继续写入文件,直到发送EOF为止?
private static void WriteTo(string …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 Kotlin 协程来处理非阻塞 I/O。场景如下:
我当前的代码如下所示(为了简洁起见,进行了简化):
private var latch = CountDownLatch(1)
private var data: Any? = null
// Async callback from non-blocking I/O
fun onReceive(data: Any) {
currentData = data
latch.countDown()
}
// Wait and consume data
fun getData(): Any? {
latch.await()
latch = CountDownLatch(1)
return currentData
}
fun processData() {
launch(CommonPool) {
while (true) {
val data = getData()
// Consume data
}
}
}
Run Code Online (Sandbox Code Playgroud)
据我了解,Kotlin 协程应该能够帮助我摆脱 CountDownLatch。读完这个(很棒的)指南后,我能想到的就是这样的:
// Wait and consume …Run Code Online (Sandbox Code Playgroud) Java 具有 ThreadLocal 变量,这些变量非常适合运行并行操作,而无需踩踏其他线程或每个循环分配,例如 OpenCV 使用videoCapture.retrieve(image),“图像”可能是线程局部变量。
Kotlin 对“协程本地”变量有任何意义吗?如果我想以他们的反例为例,但每个协程都有一个计数器,我该怎么做?
for (i in 1..1_000_000)
thread(start = true) {
c.addAndGet(i)
}
Run Code Online (Sandbox Code Playgroud) 我有一个从网络获取一些数据的自定义类。
当我获得这些数据时,我想将它设置为一个属性的值,但是当我这样做时,统一崩溃了。注释行会在没有此行的情况下生成崩溃,一切正常。请参阅下面的代码:
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
public class GetDB
{
private readonly Main m;
private readonly string Url;
public string DBData {
get
{
if(DBData == null)
return null;
else
return DBData;
}
private set
{
DBData = value;
}
}
public GetDB(Main m, string url)
{
this.m = m;
this.Url = url;
}
public void GetServerData(){
m.StartCoroutine(GetText(Url, (result) =>{
this.DBData = result; //THIS LINE CRASHES UNITY
Debug.Log(result);
}));
}
IEnumerator GetText(string url, Action<string> result) { …Run Code Online (Sandbox Code Playgroud) 我一直在研究Golang,看看它通过其创新的goroutines构造实现了一个仅限协程通道的模型,它的并发性有多好.
我立即发现令人不安的一件事是使用该Wait()方法,用于等待父母goroutine中产生的多个突出的goroutine已经完成.引用Golang文档
等待可以用来阻止所有goroutines完成
许多开发人员规定 Wait()作为实现并发性的首选方式的事实似乎与Golang使开发人员编写高效软件的使命相对立,因为阻塞效率低下,真正的异步代码永远不会阻塞.
被阻止的进程[或线程]是等待某个事件的进程[或线程],例如资源变为可用或完成I/O操作.
换句话说,被阻塞的线程将花费CPU周期无用,只需反复检查以查看其当前正在运行的任务是否可以停止等待并继续执行.
在真正的异步代码中,当协同程序遇到无法继续直到结果到达的情况时,它必须通过将其状态从运行切换到等待来将其执行发送到调度程序而不是阻塞,因此调度程序可以开始执行下一个 -来自可运行队列的内联协程.只有在需要的结果到达时,等待协程才应将其状态从等待运行变为可运行.
因此,由于Wait()直到x个goroutine被调用的块,调用Done()的goroutine Wait()将始终保持在可运行或运行状态,浪费CPU周期并依赖调度程序抢占长时间运行的goroutine,仅将其状态从运行更改为可运行,而不是将其更改为等待它应该是.
如果这一切都是真的,并且我理解如何Wait()正常工作,那么为什么人们不使用内置的Go通道来完成等待子goroutine的任务呢?如果我理解正确,发送到缓冲通道,并从任何通道读取都是异步操作,这意味着调用它们会使goroutine进入等待状态,那么为什么它们不是首选方法呢?
我引用的文章给出了一些例子.以下是作者所谓的"老派"方式:
package main
import (
"fmt"
"time"
)
func main() {
messages := make(chan int)
go func() {
time.Sleep(time.Second * 3)
messages <- 1
}()
go func() {
time.Sleep(time.Second * 2)
messages <- 2
}()
go func() {
time.Sleep(time.Second * …Run Code Online (Sandbox Code Playgroud) 谁能具体告诉我协程Lua的“味道”是什么?我问是因为Lua的协程似乎非常适合我的问题,我希望能够在各个点(可能在嵌套函数调用内)暂停函数,然后再恢复它。尽管具有类似“协程/生成器”的构造,但在C#或JavaScript中这似乎是不可能的。还有哪些其他语言支持这些类型的协程?
请看下面的代码片段。现在假设我将有数百个像“人”这样的实体。您将如何编写这样的代码以使其干净、简洁、高效、结构良好?发送
class HttpEntryPoint : CoroutineVerticle() {
private suspend fun person(r: RoutingContext) {
val res = vertx.eventBus().requestAwait<String>("/person/:id", "1").body()
r.response().end(res)
}
override suspend fun start() {
val router = Router.router(vertx)
router.get("/person/:id").coroutineHandler { ctx -> person(ctx) }
vertx.createHttpServer()
.requestHandler(router)
.listenAwait(config.getInteger("http.port", 8080))
}
fun Route.coroutineHandler(fn: suspend (RoutingContext) -> Unit) {
handler { ctx ->
launch(ctx.vertx().dispatcher()) {
try {
fn(ctx)
} catch (e: Exception) {
e.printStackTrace()
ctx.fail(e)
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud) 此 MCVE 在 Visual Studio 中运行良好。
#include <experimental/generator>
#include <iostream>
std::experimental::generator<int> f() { for (int i = 0; i < 10; ++i) co_yield i; }
int main ()
{
for (int i : f())
std::cout << i << ' ';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是在被列为完全支持或 C++20 的协程的 g++10 中,它没有。
(取出experimental并没有帮助。)
我正在编译:g++ -g -std=c++2a -fcoroutines -c main.cpp。
它抱怨没有包含文件生成器,如果我取出#include,该生成器不是 std:: 的一部分或未定义。我想在新标准中它还有另一个名字吗?或者,如果没有,我该怎么做才能获得使用 的协程co_yield?
在使用Vector3.Lerp协程内部时,我遇到了一个奇怪的问题,这是没有意义的,因为我的游戏中有很多协程,而且它们都运行良好。
我只是想通过调用协程和简单地更改对象的位置将对象从起始高度移动到最终高度。InVolo()Vector3.Lerp
float elapsedTime = 0f;
while (elapsedTime < TempoSalita)
{
transform.position = Vector3.Lerp(transform.position,
new Vector3(transform.position.x, maxHight, transform.position.z), (elapsedTime / TempoSalita));
elapsedTime += Time.deltaTime;
yield return null;
}
transform.position = new Vector3(transform.position.x, maxHight, transform.position.z);
yield return null;
Run Code Online (Sandbox Code Playgroud)
该maxHight仅仅是4F和TempoSalita为2F。协程在OnTriggerEnter 中启动并且工作正常,对象到达 y 4f 并在 2 秒内退出 while。
基本上,应该在 2 秒后elapsedTime / TempoSalita变为1,但是对象在 0.3 秒后到达结束位置,当elapsed/TempoSalita是 0.2 时,这对我来说毫无意义。Vector3.Lerp 应该在t值从 …
coroutine ×10
c# ×3
kotlin ×3
.net ×1
blocking ×1
c ×1
c++ ×1
c++20 ×1
channel ×1
concurrency ×1
go ×1
ienumerator ×1
interpreter ×1
lua ×1
properties ×1
vert.x ×1