- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
发件人:http://blog.nindalf.com/how-goroutines-work/
As the goroutines are scheduled cooperatively, a goroutine that loops continuously can starve other goroutines on the same thread.
Goroutines are cheap and do not cause the thread on which they are multiplexed to block if they are blocked on
- network input
- sleeping
- channel operations or
- blocking on primitives in the sync package.
鉴于上述情况,假设您有一些这样的代码,除了循环随机次数并打印总和之外什么都不做:
func sum(x int) {
sum := 0
for i := 0; i < x; i++ {
sum += i
}
fmt.Println(sum)
}
如果你像这样使用goroutines
go sum(100)
go sum(200)
go sum(300)
go sum(400)
如果你只有一个线程,goroutines会一个一个运行吗?
最佳答案
抢占意味着内核(运行时)允许线程运行一段特定的时间,然后在其他线程不做任何事情或不知道任何事情的情况下将执行权交给其他线程。在通常使用硬件中断实现的操作系统内核中。进程不能阻止整个操作系统。在协作式多任务线程中,线程必须显式地将执行权让给其他线程。如果不这样做,它可能会阻止整个过程甚至整个机器。 Go 就是这样做的。它有一些非常具体的点,goroutine 可以让出执行。但是,如果 goroutine 只是为 {} 执行,那么它将锁定整个进程。
但是,引用中没有提到运行时的最新变化。 fmt.Println(sum)
可能会导致其他 goroutine 被调度,因为较新的运行时将在函数调用时调用调度程序。
如果您没有任何函数调用,只是一些数学运算,那么是的,goroutine 将锁定线程,直到它退出或遇到可能让其他人执行的事情。这就是 for {}
在 Go 中不起作用的原因。更糟糕的是,由于 GC 的工作原理,即使 GOMAXPROCS > 1,它仍然会导致进程挂起,但无论如何你不应该依赖它。了解这些东西很好,但不要指望它。甚至有人提议在像您这样的循环中插入调度程序调用
Go 的运行时所做的主要事情是它尽最大努力让每个人都能执行并且不会饿死任何人。它是如何做到的,语言规范中没有具体说明,将来可能会改变。如果关于循环的提议得到实现,那么即使没有函数调用切换也可能发生。目前,您唯一应该记住的是,在某些情况下,函数调用可能会导致 goroutine 放弃执行。
为了解释 Akavall 的答案中的切换,当 fmt.Printf
被调用时,它做的第一件事是检查它是否需要增加堆栈并调用调度程序。它可能会切换到另一个 goroutine。它是否会切换取决于其他 goroutine 的状态和调度程序的具体实现。像任何调度程序一样,它可能会检查是否有应该执行的饥饿 goroutines。通过多次迭代,函数调用有更大的机会进行切换,因为其他人的饥饿时间更长。在饥饿发生之前,goroutine 完成几次迭代。
关于multithreading - Goroutines 是协作调度的。这是否意味着不让出执行的 goroutine 会导致 goroutine 一个一个运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37469995/
我在 OS X 中构建菜单栏项时找到了一些示例代码。它使用了单个 |我不确定它的实际含义。 (我想做的是在菜单项左键单击时调用一个函数,但在右键单击时显示菜单) 这是我的代码 //Get refere
为什么它在第 23 行抛出编译错误。'a' 是 Apple 类的对象,col 是包含 Apple 对象的列表,但它仍然是抛出下面提到的编译错误: 类型 Collection 中的方法 add(capt
我有一个类A,它扩展了抽象类B。 让B有一个 protected 字段值 我想在 A 中使用这个字段。如果 A 没有 value,我可以编写 this.value 从 B 获取它。 与super.va
DBLint 用于检查数据库状态。有46条规则。在 www.dblint.org 上对每条规则都有一些简单的解释,但对规则 31 的描述如下: 定义的主键不是最小键:主键是最小的 super 键。如果
var aa: (()?) = (john.residence?.address = someAddress) var bb: ()? = john.residence?.printNumberOfR
我对 jquery 的可重用插件有点陌生。我已经多次遇到这段代码,但无法弄清楚究竟发生了什么。 (function( $ ){ ... })( jQuery ); 谁能帮我解答一下吗? 最佳答案
这个问题已经有答案了: int foo (int argc, ...) vs int foo() vs int foo(void) in C (4 个回答) 已关闭 9 年前。 所以我最近在 Hack
typedef struct Element { struct Element *next; void *data; } Element; 在 pop 函数中,(!(elem = *s
数据加载两次...意味着 AsyncTask onPostExecute 加载相同的数据两次?我的 AsyncTask onPostExecute 运行两次它加载相同的数据...我正在运行异步任务以从
运行“yomeanjs”时,我无限期地挂起“这可能需要几分钟”。当我尝试运行 grunt 时,它失败了,与 npm start 相同。 我使用的是 Win 8.1,并安装了最新的 Node 和 Mon
我正在看 big nerd ranch 的“Android Programming”中的这个页面,我对下面的句子感到困惑。它声明“当 Activity 被隐藏时, Activity 对象不存在”。这让
是否 const vector意味着它的元素是const也一样? 在下面的代码中, v[0].set (1234);在 void g ( const vector & v )产生编译器错误 const
我是 xml 相关事物的新手 我无法理解: SelectNodes(@"//Form/*[. = 'on']"); 注:SelectNodes是 XmlNode 的函数.(与 XmlDocument
我想方便地控制命令行参数。因此我想使用 ShellLib。 我的代码是这样的: ... #include ... EFI_STATUS EFIAPI UefiMain ( EFI_HANDL
着眼于更正 Debian 上/etc/init.d/hostapd 中的一个问题。但是,我不知道这行代码是做什么的,也不知道它是如何工作的 [ -n "$DAEMON_CONF" ] || exit
有没有人遇到过类似我下图所示的情况? 我有一个变量 landingBools.didSlowPast40Knots(正如您从调试打印输出中看到的那样)为假,但出于某种原因,if 语句评估为真。 知道为
我设法使用 flexbox 和一些非常基本的 JavaScript 为自己构建了三个下拉菜单。 因为我不太了解,所以我使用了一个简单的函数三次,而不是使用参数、变量和其他东西。我将其称为丑陋的“蛮力”
这周刚开始学习 javascript。我有一个非常菜鸟的问题。 exports.displayName = (undefined: ?string); 在 React Native 中意味着什么? 这
我正在阅读有关 NaN here 的内容它说: A comparison with a NaN always returns an unordered result even when compari
编码格式:引入*表示“从头开始重复”。例子。输入-{a,b,a,b,c,a,b,a,b,c,d}可以写成{a,b,*,c,*,d}。输出:5;例如2:ABCABCE,输出- 5。 这里*表示从头开始重
我是一名优秀的程序员,十分优秀!