Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin和x27的螺纹安全性;s序列生成器_Kotlin_Sequence_Kotlin Coroutines - Fatal编程技术网

Kotlin和x27的螺纹安全性;s序列生成器

Kotlin和x27的螺纹安全性;s序列生成器,kotlin,sequence,kotlin-coroutines,Kotlin,Sequence,Kotlin Coroutines,鉴于存在一种在Kotlin中标记序列和混合命令式代码的方法,那么作为sequence函数的参数的lambda中所需的代码是否需要是线程安全的 例如,以下各项是否安全: var x: Int = 5 fun someSequence(): Sequence<Int> = sequence { while (true) { x++ yield(x) } } fun main(args: Array<String>) {

鉴于存在一种在Kotlin中标记序列和混合命令式代码的方法,那么作为
sequence
函数的参数的lambda中所需的代码是否需要是线程安全的

例如,以下各项是否安全:

var x: Int = 5

fun someSequence(): Sequence<Int> = sequence {
    while (true) {
        x++
        yield(x)
    }
}

fun main(args: Array<String>) {
    val seq = someSequence()
    seq.take(200).forEach(::println)
}
我担心缓存读取通常不会固定到特定的线程。我设想两种备选方案:

  • sequence
    函数需要特别注意,以便生成下一个元素的lambda始终在同一线程中执行。协同路由/挂起函数是一个实现细节,它临时将控制流传输给序列的使用者。这就是
    @RestrictSuspension
    的意义吗?(来自)

  • 传递给
    序列的lambda必须是线程安全的。为什么政府对这件事如此缄默?也只涵盖非常简单的用例


  • 请详细说明哪种情况以及原因。

    序列的协程在调用线程上执行,因此所有线程安全问题都是调用方的责任


    通常,如果您将序列传递给其他线程,以便每次在另一个线程上恢复协同路由,那么您需要确保的是,从暂停到恢复之间建立了“发生在之前”的关系,提供整体效果,就像协程在单个线程上顺序执行一样。

    对于我的用例,调用线程将始终是主线程。这意味着没有中间人?是否真的有一个成熟的协同程序,或者
    SequenceScope
    只是使用协同程序机器的一部分?我仍然对协同路由如何实现顺序数据结构的构造感到惊讶。不,运行协同路由不需要调度程序,它是在它们之上的一层。而且序列从不使用它们。您可以查看它,它向您展示了使用您自己的代码暂停和恢复协同程序的机制。您可以很容易地从该代码推断出每次序列恢复时将生成另一个序列成员的代码。您的链接答案非常有启发性,谢谢。我现在明白了调度程序和协同程序不一定是耦合的(这正是答案的最后一段),并且可以很好地与序列主题相关。已解决:)
    public fun <T> sequence(@BuilderInference block: suspend SequenceScope<T>.() -> Unit): Sequence<T> = Sequence { iterator(block) }
    
    public fun <T> iterator(@BuilderInference block: suspend SequenceScope<T>.() -> Unit): Iterator<T> {
        val iterator = SequenceBuilderIterator<T>()
        iterator.nextStep = block.createCoroutineUnintercepted(receiver = iterator, completion = iterator)
        return iterator
    }