为什么goroutine没有身份 [英] Why does a goroutine have no identity

查看:83
本文介绍了为什么goroutine没有身份的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是golang的新手,正在阅读gopl书中的示例.

I new to golang and I am reading the example from the book gopl.

Go编程语言书籍的9.8.4节解释了为什么Goroutines没有程序员可以访问的身份概念

Section 9.8.4 of The Go Programming Language book explains why Goroutines have no notion of identity that is accessible to the programmer

Goroutine没有程序员可以访问的身份概念.这是设计使然,因为线程本地存储会被滥用.例如,在以具有线程本地存储的语言实现的Web服务器中,许多功能通常会通过查看该存储来查找有关HTTP请求的信息,这些信息当前正以其名义工作.但是,就像过度依赖全局变量的程序一样,这可能会导致不健康的远距离操作",在这种情况下,函数的行为不仅取决于其参数,还取决于线程中的身份.它运行.因此,如果线程的身份应更改(例如,要求某些工作线程帮助),则该函数会神秘地发生错误行为.

Goroutines have no notion of identity that is accessible to the programmer. This is by design, since thread-local storage tends to be abused. For example, in a web server implemented in a language with thread-local storage, it’s common for many functions to find information about the HTTP request on whose behalf they are currently working by looking in that storage. However, just as with programs that rely excessively on global variables, this can lead to an unhealthy ‘‘action at a distance’’ in which the behavior of a function is not determined by its arguments alone, but by the identity of the thread in which it runs. Consequently, if the identity of the thread should change—some worker threads are enlisted to help, say—the function misbehaves mysteriously.

,并使用Web服务器的示例来说明这一点.但是,我很难理解为什么所谓的远距离行动"是一种不好的做法,以及这如何导致

and use the example of web server to illustrate this point. However, I have difficulty in understanding why the so called "action at a distance" is a bad practice and how this leads to

一个函数不是仅由其参数确定,而是由其运行的线程的标识确定.

a function is not determined by its arguments alone, but by the identity of the thread in which it runs.

任何人都可以对此进行解释(最好是简短的代码段)

could anyone give an explanation for this(preferably in short code snippets)

感谢您的帮助!

推荐答案

假设我们有以下代码:

func doubler(num int) { 
    return num + num
}

doubler(5)将返回10. go doubler(5)也将返回10.

doubler(5) will return 10. go doubler(5) will also return 10.

如果需要,可以对某种线程本地存储执行相同的操作

You can do the same with some sort of thread-local storage, if you want:

func doubler() { 
    return getThreadLocal("num") + getThreadLocal("num")
}

我们可以用类似的方式运行它:

And we could run this with something like:

go func() {
    setThreadLocal("num", 10)
    doubler()
}()

但是哪个更清楚?显式传递num参数的变量,还是神奇地"从某种线程本地存储中获取变量的变量?

But which is clearer? The variant which explicitly passes the num argument, or the variant which "magically" gets this from sort of thread-local storage?

这是远距离行动"的意​​思.线setThreadLocal("num", 10)(相距较远)影响doubler()的行为.

This is what is meant with "action at a distance". The line setThreadLocal("num", 10) (which is distant) affects how doubler() behaves.

这个例子显然是人为的,但是相同的原理适用于更多的实际例子.例如,在某些环境中,使用线程本地存储的东西(例如用户信息或其他全局"变量)并不少见.

This example is clearly artificial, but the same principle applies with more real examples. For example, in some environments it's not uncommon to use thread-local store things such as user information, or other "global" variables.

这就是为什么您引用的段落将其与全局变量进行比较的原因:线程本地存储全局变量,仅适用于当前线程.

This is why the paragraph you quoted compared it to global variables: thread-local storage are global variables, applicable only to the current thread.

当您将参数作为参数传递时,定义起来会更加清晰.在调试或编写测试时,无需考虑任何魔术(通常是未记录的)全局状态.

When you passing parameters as arguments things are a lot clearer defined. There is no magic (often undocumented) global state that you need to think of when debugging things or writing tests.

这篇关于为什么goroutine没有身份的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆