goroutine的问题

55 views
Skip to first unread message

洪瑞琦

unread,
Jan 24, 2012, 4:00:13 AM1/24/12
to golang...@googlegroups.com
发生系统调用阻塞的时候切换到另外一个goroutine运行,此时另一个goroutine是新建一个线程运行么?
GOMAXPROC设置的线程数具体是指什么?默认单线程的时候是怎么处理goroutine的切换的?

谢谢!!

shiwei xu

unread,
Jan 24, 2012, 5:22:29 AM1/24/12
to golang...@googlegroups.com
发生系统调用切换goroutine但不一定切换到其他线程。切换的单位是协程,在 windows 下叫 fiber。

2012/1/24 洪瑞琦 <hong...@gmail.com>
发生系统调用阻塞的时候切换到另外一个goroutine运行,此时另一个goroutine是新建一个线程运行么?
GOMAXPROC设置的线程数具体是指什么?默认单线程的时候是怎么处理goroutine的切换的?

谢谢!!

--
来自: Golang-China ~ 中文Go语言技术邮件列表
发言: golang...@googlegroups.com
详情: http://groups.google.com/group/golang-china
官网: http://golang-china.org/
翻译: http://github.com/border/golang-china/
论坛: http://bbs.golang-china.org/
@golangchina



--
许式伟

wonderfo

unread,
Jan 25, 2012, 10:41:58 PM1/25/12
to golang-china
在 FAQ 中看到相关条目,没有深入研究测试,给了粗略翻译(英语成绩不好,如果理解有误,还望各位同学指正)

1、为什么使用 goroutines 代替线程 http://weekly.golang.org/doc/go_faq.html#goroutines

  摘录:When a coroutine blocks, such as by calling a blocking system call, the run-time automatically moves other coroutines on the same operating system thread to a different, runnable thread so they won't be blocked.
  勉强:当一个协同程序阻塞时,例如呼叫一个阻塞的系统调用,在同一线程下的其他协同程序,会被“Go运行时”自动调度到另一个可运行线程,这样就不会被阻塞了。

  摘录:To make the stacks small, Go's run-time uses segmented stacks. A newly minted goroutine is given a few kilobytes, which is almost always enough. When it isn't, the run-time allocates (and frees) extension segments automatically. The overhead averages about three cheap instructions per function call. It is practical to create hundreds of thousands of goroutines in the same address space. If goroutines were just threads, system resources would run out at a much smaller number.
  翻译:为减少栈空间占用,“Go运行时”使用分段栈。新建的goroutine先分配几KB栈空间,这在大多数情况下已经够用。如果栈空间不够,“Go运行时”会分配(或释放)更多的栈片段。函数调用平均使用3个简单指令。因此在实践中,在相同地址空间创建数十万 goroutines 是可行的。如果使用线程,由于系统资源的限制,相比之下能运行 goroutines 将会少很多。


2、为什么我的多goroutine程序没有充分利用多CPU http://weekly.golang.org/doc/go_faq.html#Why_no_multi_CPU

  摘录:Under the gc compilers you must set GOMAXPROCS to allow the run-time support to utilise more than one OS thread. Under gccgo an OS thread will be created for each goroutine, and GOMAXPROCS is effectively equal to the number of running goroutines.
  翻译:在 gc 编译器下,你必须设置 GOMAXPROCS 允许“Go运行时”使用多个线程。在 gccgo 编译器下,每个 goroutine 都会创建一个线程,GOMAXPROCS 代表运行的 goroutine 个数。

 【困惑】Under gccgo an OS thread will be created for each goroutine 英文不好,这句话理解有疑惑,个人瞎猜,在gccgo下是不是用类似线程池的机制,来运行 gorouitne 呀,否则每个 goroutine 创建一个线程,损耗太大了吧,和上一个条目的意思也不符呀。有点迷糊,恳请各位同学指正。


3、为什么 GOMAXPROCS>1 程序有时反而更慢 http://weekly.golang.org/doc/go_faq.html#Why_GOMAXPROCS

  摘录:Go's goroutine scheduler is not as good as it needs to be. In future, it should recognize such cases and optimize its use of OS threads. For now, GOMAXPROCS should be set on a per-application basis.
  翻译:Go 的 goroutine 调度器还没有达到预期目标。将来,它应自动识别这些情况,并优化线程的使用。现在,程序只能手工设置 GOMAXPROCS 。
--------------
wonderfo

洪瑞琦

unread,
Jan 26, 2012, 1:31:52 AM1/26/12
to golang...@googlegroups.com
谢谢wonderfo

当一个协同程序阻塞时,例如呼叫一个阻塞的系统调用,在同一线程下的其他协同程序,会被“Go运行时”自动调度到另一个可运行线程,这样就不会被阻塞了。

默认的时候GOMAXPROC=1,只有一个线程,那调度到另一个可运行线程是什么意思呢?还是说GOMAXPROC指的是运行用户代码(非阻塞)的最大线程数?

2012/1/26 wonderfo <wond...@yeah.net>

洪瑞琦

unread,
Jan 26, 2012, 2:55:49 AM1/26/12
to golang...@googlegroups.com
看了一下邮件列表:

https://groups.google.com/group/golang-nuts/browse_thread/thread/4387e0820013713a/3e27a0f3ae710f30?#3e27a0f3ae710f30

我的理解是:

    GOMAXPROC指定的是同时运行(不包括阻塞和等待)的最大线程数。goroutine运行结束时,线程不会销毁。

    GOMAXPROC=1时,初始的时候只有一个线程A。当线程A中的goroutine 1因为系统调用或channel而阻塞时,新建一个线程B,将可运行goroutine切换到线程B中运行(goroutine 2)。

    线程B中的goroutine 2发生阻塞时:若线程A中的goroutine 1仍阻塞,则新建线程C执行可运行的goroutine 3;若线程A中goroutine 1已可运行,则选择一个goroutine在线程A中运行(不一定是goroutine 1?)

    实际存在的线程数量与GOMAXPROC无关。

由FAQ中的这句话有个疑问:

    the run-time automatically moves other coroutines on the same operating system thread to a different

按照这句话,在上面的描述中,如果线程B中的goroutine阻塞时,线程A中有可运行的goroutine,而线程B中没有,此时线程A中的goroutine是否不会被切换到新的线程中运行?

Liigo Zhuang

unread,
Jan 26, 2012, 11:55:02 AM1/26/12
to golang...@googlegroups.com

Goroutine的协调管理是go语言的核心机制,是由编译器具体调控的,对程序员来说是透明的,我们只要认为或相信它内部一定会运作的很好就可以了。综合现有信息来看,goroutine机制设计的很理想,但目前编译器的实现上还不是很完美,有许多需要改进和完善的地方,会越来越好;就算目前的实现也大概足够实用(有人评估过吗)。如果对goroutine内部管理/调控/运作机制感兴趣,可以研究下go语言编译器源代码(go语言目前有两个编译器,内部实现也不一样)。

--

mon...@gmail.com

unread,
Jan 26, 2012, 2:18:01 PM1/26/12
to golang...@googlegroups.com
wonderfo wrote, On 01/25/2012 10:41 PM:
> �� FAQ �п��������Ŀ��û�������о����ԣ����˴��Է��루Ӣ��ɼ����ã����������󣬻����λͬѧָ��
>
> 1��Ϊʲôʹ�� goroutines �����߳� http://weekly.golang.org/doc/go_faq.html#goroutines
>
> ����ժ¼��When a coroutine blocks, such as by calling a blocking system call, the run-time automatically moves other coroutines on the same operating system thread to a different, runnable thread so they won't be blocked.
> ������ǿ����һ��Эͬ��������ʱ���������һ�������ϵͳ���ã���ͬһ�߳��µ�����Эͬ���򣬻ᱻ��Go����ʱ���Զ����ȵ���һ���������̣߳�����Ͳ��ᱻ�����ˡ�
>
> ����ժ¼��To make the stacks small, Go's run-time uses segmented stacks. A newly minted goroutine is given a few kilobytes, which is almost always enough. When it isn't, the run-time allocates (and frees) extension segments automatically. The overhead averages about three cheap instructions per function call. It is practical to create hundreds of thousands of goroutines in the same address space. If goroutines were just threads, system resources would run out at a much smaller number.
> �������룺Ϊ����ջ�ռ�ռ�ã���Go����ʱ��ʹ�÷ֶ�ջ���½���goroutine�ȷ��伸KBջ�ռ䣬���ڴ����������Ѿ����á����ջ�ռ䲻������Go����ʱ������䣨���ͷţ�����ջƬ�Ρ��������ƽ��ʹ��3����ָ������ʵ���У�����ͬ��ַ�ռ䴴����ʮ�� goroutines �ǿ��еġ����ʹ���̣߳�����ϵͳ��Դ�����ƣ����֮�������� goroutines �����ٺܶࡣ
>
>
> 2��Ϊʲô�ҵĶ�goroutine����û�г�����ö�CPU http://weekly.golang.org/doc/go_faq.html#Why_no_multi_CPU
>
> ����ժ¼��Under the gc compilers you must set GOMAXPROCS to allow the run-time support to utilise more than one OS thread. Under gccgo an OS thread will be created for each goroutine, and GOMAXPROCS is effectively equal to the number of running goroutines.
> �������룺�� gc �������£���������� GOMAXPROCS ���?Go����ʱ��ʹ�ö���̡߳��� gccgo �������£�ÿ�� goroutine ���ᴴ��һ���̣߳�GOMAXPROCS ������е� goroutine ����
>
> ��������Under gccgo an OS thread will be created for each goroutine Ӣ�IJ��ã���仰������ɻ󣬸���Ϲ�£���gccgo���Dz����������̳߳صĻ��ƣ������� gorouitne ѽ������ÿ�� goroutine ����һ���̣߳����̫���˰ɣ�����һ����Ŀ����˼Ҳ����ѽ���е��Ժ�����λͬѧָ��
>

�Dz���ʹ���̳߳ز�֪������gccgo��ȷ��һ��goroutineһ���̡߳�����Go1�᲻
�����޸ģ��Ͳ�����ˡ���ӡ���к���Go1�ļƻ����д�����gccgo��5/6/8gͳһ
�ġ���֪�����������������ͱ�׼��ͳһ�������ڲ�ʵ��Ҳ����ͳһ�������
˵�������˾��û���5/6/8g���
>
> 3��Ϊʲô GOMAXPROCS>1 ������ʱ������� http://weekly.golang.org/doc/go_faq.html#Why_GOMAXPROCS
>
> ����ժ¼��Go's goroutine scheduler is not as good as it needs to be. In future, it should recognize such cases and optimize its use of OS threads. For now, GOMAXPROCS should be set on a per-application basis.
> �������룺Go �� goroutine ��������û�дﵽԤ��Ŀ�ꡣ��������Ӧ�Զ�ʶ����Щ��������Ż��̵߳�ʹ�á����ڣ�����ֻ���ֹ����� GOMAXPROCS ��

�����е����壺For now, GOMAXPROCS should be set on a per-application
basis. ��÷���Ϊ��Ŀǰ��GOMAXPROCS����Ӧ�ø��Ӧ�ó���ĸ���������ֱ�
����

> --------------
> wonderfo
>> ����ϵͳ�����л�goroutine����һ���л��������̡߳��л��ĵ�λ��Э�̣��� windows �½� fiber��
>>
>> 2012/1/24 ������<hong...@gmail.com>
>>
>>> ����ϵͳ���������ʱ���л�������һ��goroutine���У���ʱ��һ��goroutine���½�һ���߳�����ô��
>>> GOMAXPROC���õ��߳��������ָʲô��Ĭ�ϵ��̵߳�ʱ������ô����goroutine���л��ģ�
>>>
>>> лл����
>>>
>>> --
>>> ����: Golang-China ~ ����Go���Լ����ʼ��б�
>>> ����: golang...@googlegroups.com
>>> ����: http://groups.google.com/group/golang-china
>>> ����: http://golang-china.org/
>>> ����: http://github.com/border/golang-china/
>>> ��̳: http://bbs.golang-china.org/
>>> @golangchina
>>>
>>
>>
>>
>> --
>> ��ʽΰ
>> https://qbox.me
>>
>> --
>> ����: Golang-China ~ ����Go���Լ����ʼ��б�
>> ����: golang...@googlegroups.com
>> ����: http://groups.google.com/group/golang-china
>> ����: http://golang-china.org/
>> ����: http://github.com/border/golang-china/
>> ��̳: http://bbs.golang-china.org/
>> @golangchina
>

wonderfo

unread,
Jan 26, 2012, 7:55:37 PM1/26/12
to golang-china
呵呵,谢谢 monnand 指正。(^_^)

另外,看了 fango 的博文,根据文中的提示,找到源文件 proc.c,里面有句注释验证了 洪瑞琦 的想法,$GOMAXPROCS 确实只是最大使用核心的近似值:

$GOMAXPROCS is thus an approximation of the maximum number of cores to use.


--------------
wonderfo
>wonderfo wrote, On 01/25/2012 10:41 PM:
>> 在 FAQ 中看到相关条目,没有深入研究测试,给了粗略翻译(英语成绩不好,如果理解有误,还望各位同学指正)
>>
>> 1、为什么使用 goroutines 代替线程 http://weekly.golang.org/doc/go_faq.html#goroutines
>>
>>   摘录:When a coroutine blocks, such as by calling a blocking system call, the run-time automatically moves other coroutines on the same operating system thread to a different, runnable thread so they won't be blocked.
>>   勉强:当一个协同程序阻塞时,例如呼叫一个阻塞的系统调用,在同一线程下的其他协同程序,会被“Go运行时”自动调度到另一个可运行线程,这样就不会被阻塞了。
>>
>>   摘录:To make the stacks small, Go's run-time uses segmented stacks. A newly minted goroutine is given a few kilobytes, which is almost always enough. When it isn't, the run-time allocates (and frees) extension segments automatically. The overhead averages about three cheap instructions per function call. It is practical to create hundreds of thousands of goroutines in the same address space. If goroutines were just threads, system resources would run out at a much smaller number.
>>   翻译:为减少栈空间占用,“Go运行时”使用分段栈。新建的goroutine先分配几KB栈空间,这在大多数情况下已经够用。如果栈空间不够,“Go运行时”会分配(或释放)更多的栈片段。函数调用平均使用3个简单指令。因此在实践中,在相同地址空间创建数十万 goroutines 是可行的。如果使用线程,由于系统资源的限制,相比之下能运行 goroutines 将会少很多。
>>
>>
>> 2、为什么我的多goroutine程序没有充分利用多CPU http://weekly.golang.org/doc/go_faq.html#Why_no_multi_CPU
>>
>>   摘录:Under the gc compilers you must set GOMAXPROCS to allow the run-time support to utilise more than one OS thread. Under gccgo an OS thread will be created for each goroutine, and GOMAXPROCS is effectively equal to the number of running goroutines.
>>   翻译:在 gc 编译器下,你必须设置 GOMAXPROCS 允许“Go运行时”使用多个线程。在 gccgo 编译器下,每个 goroutine 都会创建一个线程,GOMAXPROCS 代表运行的 goroutine 个数。
>>
>>  【困惑】Under gccgo an OS thread will be created for each goroutine 英文不好,这句话理解有疑惑,个人瞎猜,在gccgo下是不是用类似线程池的机制,来运行 gorouitne 呀,否则每个 goroutine 创建一个线程,损耗太大了吧,和上一个条目的意思也不符呀。有点迷糊,恳请各位同学指正。
>>
>
>是不是使用线程池不知道,但gccgo的确是一个goroutine一个线程。至于Go1会不
>会有修改,就不清楚了。我印象中好像Go1的计划中有打算让gccgo和5/6/8g统一
>的。不知道究竟仅仅是是语法和标准库统一,还是内部实现也尽量统一。不过基本
>说来,个人觉得还是5/6/8g最靠谱
>>
>> 3、为什么 GOMAXPROCS>1 程序有时反而更慢 http://weekly.golang.org/doc/go_faq.html#Why_GOMAXPROCS
>>
>>   摘录:Go's goroutine scheduler is not as good as it needs to be. In future, it should recognize such cases and optimize its use of OS threads. For now, GOMAXPROCS should be set on a per-application basis.
>>   翻译:Go 的 goroutine 调度器还没有达到预期目标。将来,它应自动识别这些情况,并优化线程的使用。现在,程序只能手工设置 GOMAXPROCS 。
>
>翻译有点歧义:For now, GOMAXPROCS should be set on a per-application
>basis. 最好翻译为:目前,GOMAXPROCS还是应该根据应用程序的各自情况,分别
>调整。

洪瑞琦

unread,
Jan 29, 2012, 8:26:08 PM1/29/12
to golang...@googlegroups.com
固定GOMAXPROC=1的时候,需要加锁吗?

2012/1/27 wonderfo <wond...@yeah.net>

wonderfo

unread,
Jan 30, 2012, 12:13:09 AM1/30/12
to golang-china
谈点个人理解,不知是否洪兄提问的原义:

从生产实践的角度,如果程序的语义确实是并发,而且有共享资源,就应该用 chan 设定共享资源的访问次序 ,安心且规范
从研究好奇的角度,GOMAXPROC=1 时不加锁,是否能保证资源某时刻的唯一访问,我个人不知道,没研究这么深了。

--------------
wonderfo

Sparkle

unread,
Jan 30, 2012, 9:39:15 PM1/30/12
to golang...@googlegroups.com
go�ڱ����ڻ����Զ���������˳��goroutine���治Ӧ����������ⲿ����

�� 2012/1/30 13:13, wonderfo �:
> ̸�������⣬��֪�Ƿ�������ʵ�ԭ�壺
>
> �����ʵ��ĽǶȣ������������ȷʵ�Dz����������й�����Դ����Ӧ���� chan �趨������Դ�ķ��ʴ��� �������ҹ淶
> ���о�����ĽǶȣ�GOMAXPROC=1 ʱ�������Ƿ��ܱ�֤��Դijʱ�̵�Ψһ���ʣ��Ҹ��˲�֪����û�о���ô���ˡ�
>
> --------------
> wonderfo
>> �̶�GOMAXPROC=1��ʱ����Ҫ������
>>
>> 2012/1/27 wonderfo <wond...@yeah.net>
>>
>>> �Ǻǣ�лл monnand ָ��(^_^)
>>>
>>> ���⣬���� fango �IJ��ģ�������е���ʾ���ҵ�Դ�ļ� proc.c�������о�ע����֤�� ������ ���뷨��$GOMAXPROCS
>>> ȷʵֻ�����ʹ�ú��ĵĽ���ֵ��


>>>
>>> $GOMAXPROCS is thus an approximation of the maximum number of cores to use.
>>>
>>>
>>> --------------
>>> wonderfo
>>>> wonderfo wrote, On 01/25/2012 10:41 PM:

>>>>> �� FAQ �п��������Ŀ��û�������о����ԣ����˴��Է��루Ӣ��ɼ����ã����������󣬻����λͬѧָ��
>>>>>
>>>>> 1��Ϊʲôʹ�� goroutines �����߳�
>>> http://weekly.golang.org/doc/go_faq.html#goroutines

>>>>> ժ¼��When a coroutine blocks, such as by calling a blocking system call,


>>> the run-time automatically moves other coroutines on the same operating
>>> system thread to a different, runnable thread so they won't be blocked.

>>> ��ǿ����һ��Эͬ��������ʱ���������һ�������ϵͳ���ã���ͬһ�߳��µ�����Эͬ���򣬻ᱻ��Go����ʱ���Զ����ȵ���һ���������̣߳�����Ͳ��ᱻ�����ˡ�

>>>>> ժ¼��To make the stacks small, Go's run-time uses segmented stacks. A


>>> newly minted goroutine is given a few kilobytes, which is almost always
>>> enough. When it isn't, the run-time allocates (and frees) extension
>>> segments automatically. The overhead averages about three cheap
>>> instructions per function call. It is practical to create hundreds of
>>> thousands of goroutines in the same address space. If goroutines were just
>>> threads, system resources would run out at a much smaller number.

>>> ���룺Ϊ����ջ�ռ�ռ�ã���Go����ʱ��ʹ�÷ֶ�ջ���½���goroutine�ȷ��伸KBջ�ռ䣬���ڴ����������Ѿ����á����ջ�ռ䲻������Go����ʱ������䣨���ͷţ�����ջƬ�Ρ��������ƽ��ʹ��3����ָ������ʵ���У�����ͬ��ַ�ռ䴴����ʮ��
>>> goroutines �ǿ��еġ����ʹ���̣߳�����ϵͳ��Դ�����ƣ����֮�������� goroutines �����ٺܶࡣ
>>>>>
>>>>> 2��Ϊʲô�ҵĶ�goroutine����û�г�����ö�CPU
>>> http://weekly.golang.org/doc/go_faq.html#Why_no_multi_CPU

>>>>> ժ¼��Under the gc compilers you must set GOMAXPROCS to allow the run-time


>>> support to utilise more than one OS thread. Under gccgo an OS thread will
>>> be created for each goroutine, and GOMAXPROCS is effectively equal to the
>>> number of running goroutines.

>>>>> ���룺�� gc �������£���������� GOMAXPROCS ���?Go����ʱ��ʹ�ö���̡߳��� gccgo �������£�ÿ�� goroutine
>>> ���ᴴ��һ���̣߳�GOMAXPROCS ������е� goroutine ����

>>>>> ������Under gccgo an OS thread will be created for each goroutine


>>> Ӣ�IJ��ã���仰������ɻ󣬸���Ϲ�£���gccgo���Dz����������̳߳صĻ��ƣ������� gorouitne ѽ������ÿ�� goroutine
>>> ����һ���̣߳����̫���˰ɣ�����һ����Ŀ����˼Ҳ����ѽ���е��Ժ�����λͬѧָ��
>>>> �Dz���ʹ���̳߳ز�֪������gccgo��ȷ��һ��goroutineһ���̡߳�����Go1�᲻
>>>> �����޸ģ��Ͳ�����ˡ���ӡ���к���Go1�ļƻ����д�����gccgo��5/6/8gͳһ
>>>> �ġ���֪�����������������ͱ�׼��ͳһ�������ڲ�ʵ��Ҳ����ͳһ�������
>>>> ˵�������˾��û���5/6/8g���
>>>>> 3��Ϊʲô GOMAXPROCS>1 ������ʱ�������
>>> http://weekly.golang.org/doc/go_faq.html#Why_GOMAXPROCS

>>>>> ժ¼��Go's goroutine scheduler is not as good as it needs to be. In


>>> future, it should recognize such cases and optimize its use of OS threads.
>>> For now, GOMAXPROCS should be set on a per-application basis.

Reply all
Reply to author
Forward
0 new messages