go routine execution and I/O

3,231 views
Skip to first unread message

Abhijit Kadam

unread,
Jan 6, 2014, 1:19:47 AM1/6/14
to golan...@googlegroups.com

Hi All,

I am learning golang and want to know more on concurrent execution of go routines. When a go routine performs an I/O then whether that routine is suspended until the I/O is completed? Or the scheduler just takes turns moving to other routines and back and frequently check for I/O completion? In other languages (runtimes), they use thread pool and do I/O in async way so that single thread is not blocked while I/O is happening and instead that thread serve other requests/tasks.

 In golang “go routine” is light weight and we can have thousands of them so async I/O may not be significant. Although we can have several routines executed by single or multiple threads when performing I/O if runtime refrains not visiting that routine unless I/O is completed then it would be doubly efficient. Want to know what happens under the hood?

Thanks,

Abhijit

Didier Spezia

unread,
Jan 6, 2014, 4:26:19 AM1/6/14
to golan...@googlegroups.com
When a goroutine performs a blocking, non multiplexable, I/O (block device for instance),
it will be blocked, but none of the other goroutines will be blocked. Physically, you will
have at least one physical thread per blocked goroutine (on system call, C code, etc ...),
plus a number of threads to run non blocked goroutines (i.e. GOMAXPROCS).

You may want to have a look at:

Regards,
Didier.

Abhijit Kadam

unread,
Jan 6, 2014, 6:25:30 AM1/6/14
to Didier Spezia, golan...@googlegroups.com
This means for application (go code) things appear non blocking as one or the other free thread can continue scheduling and executing routines. However the runtime at the core is not doing non blocking I/O. Which means if we have an I/O intensive work to be done, then most of the threads would be blocked for the I/O and this would affect GOMAXPROCS executing go code, is it not?

So the concurrency model will be effective in case of CPU intensive tasks. However in case of I/O intensive latency operations, will the blocking I/O at system level affect the overall go routines execution? So in case of high I/O if you have limited cores then this can lead to same problems as that of other frameworks. Also there is no way of explicitly doing non-blocking I/O, is there?


--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/Luje-okL4jI/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Dmitry Vyukov

unread,
Jan 6, 2014, 7:19:58 AM1/6/14
to Abhijit Kadam, Didier Spezia, golang-nuts
Go uses non-blocking IO for network operations in net package. So it
as efficient as it could be.
For other IO, syscalls and C calls Go consumes thread per call.
It could use non-blocking IO for file operations as well. But this is
not implemented yet. There is an open issue for this.
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an

Niklas Schnelle

unread,
Jan 6, 2014, 7:24:57 AM1/6/14
to golan...@googlegroups.com, Abhijit Kadam, Didier Spezia
Also afaik threads blocked on IO don't count towards GOMAXPROCS, right?

Dmitry Vyukov

unread,
Jan 6, 2014, 7:29:19 AM1/6/14
to Niklas Schnelle, golang-nuts, Abhijit Kadam, Didier Spezia
yes, that's correct

On Mon, Jan 6, 2014 at 4:24 PM, Niklas Schnelle
<niklas....@gmail.com> wrote:
> Also afaik threads blocked on IO don't count towards GOMAXPROCS, right?
>

Didier Spezia

unread,
Jan 6, 2014, 7:32:03 AM1/6/14
to golan...@googlegroups.com, Didier Spezia

Well first, all I/Os that can be multiplexed using epoll/kqueue/... will be multiplexed by the runtime.
It includes all network/pipe related I/Os.

Now for the I/Os related to disks (or system calls, or just C calls), extra threads will be used.
But note that GOMAXPROCS does not cap the global number of threads, but only the number
of threads executing Go code.

So if you have a disk I/O bound app using 10 goroutines, you will likely have 10 system threads
corresponding to the 10 goroutines blocked on I/Os plus GOMAXPROCS threads to run the other
eventual goroutines.

IMO, the only downside of this approach is the number of threads it can generate in pathological cases.

Regards,
Didier.

Abhijit Kadam

unread,
Jan 6, 2014, 8:20:30 AM1/6/14
to Didier Spezia, golan...@googlegroups.com
Threads blocked on IO don't count towards GOMAXPROCS, but too many system threads blocked on I/O would affect the overall performance.

Good to know that net package uses non blocking socket IO and there are plans to make disk IO non blocking. You said there is open issue, where can we see such open issues?

Also how the database sql driver communicates? Does it block thread unless we get database response or uses net package non blocking IO?

Now I think even though today some IO is blocking, that can be changed tomorrow to non blocking without breaking the API's and user code because of the "golang system/runtime" is managing the threads and routines. Correct?

Dmitry Vyukov

unread,
Jan 6, 2014, 8:23:37 AM1/6/14
to Abhijit Kadam, Didier Spezia, golang-nuts
On Mon, Jan 6, 2014 at 5:20 PM, Abhijit Kadam <abhij...@gmail.com> wrote:
> Threads blocked on IO don't count towards GOMAXPROCS, but too many system
> threads blocked on I/O would affect the overall performance.
>
> Good to know that net package uses non blocking socket IO and there are
> plans to make disk IO non blocking. You said there is open issue, where can
> we see such open issues?

https://code.google.com/p/go/issues/detail?id=6222
https://code.google.com/p/go/issues/detail?id=6817


> Also how the database sql driver communicates? Does it block thread unless
> we get database response or uses net package non blocking IO?

It depends on driver implementation.


>
> Now I think even though today some IO is blocking, that can be changed
> tomorrow to non blocking without breaking the API's and user code because of
> the "golang system/runtime" is managing the threads and routines. Correct?

correct
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an

Bienlein

unread,
Jan 6, 2014, 9:02:16 AM1/6/14
to golan...@googlegroups.com, Abhijit Kadam, Didier Spezia


Am Montag, 6. Januar 2014 14:23:37 UTC+1 schrieb Dmitry Vyukov:

> Also how the database sql driver communicates? Does it block thread unless
> we get database response or uses net package non blocking IO?

It depends on driver implementation.

This is nice. Some beginner question: Are there some db drivers for Go that make use of this and thus become non-blocking? Is the same thing possible in Java, that is write a database driver that comminucates with the JVM scheduler? AFAIK the JVM scheduler has no interface that some driver can communicate with it as in Go. Just to build up my understanding and to find a good reason why I can explain why I want to use Go ...

Thanks, Bienlein

Dmitry Vyukov

unread,
Jan 6, 2014, 9:33:32 AM1/6/14
to Bienlein, golang-nuts, Abhijit Kadam, Didier Spezia
If the driver uses net package to communicate with DB process (which
is quite likely), then it uses this feature automatically.
If/when file/pipe IO is make non-blocking as well, all drivers that
use files/pipes will use this feature automatically as well.
Also a driver could use a single thread for IO and park/unpark user
goroutines on channels. That would have the same effect.

Bienlein

unread,
Jan 6, 2014, 10:29:12 AM1/6/14
to golan...@googlegroups.com, Bienlein, Abhijit Kadam, Didier Spezia

If the driver uses net package to communicate with DB process (which
is quite likely), then it uses this feature automatically.
If/when file/pipe IO is make non-blocking as well, all drivers that
use files/pipes will use this feature automatically as well.
Also a driver could use a single thread for IO and park/unpark user
goroutines on channels. That would have the same effect.


Thanks for your answer, Dmitry. Just for my records for anyone who knows: That kind of yielding as in Go to achieve non-blokcing I/O cannot be done with Java or on the JVM?
Not that I had a problem if it couldn't be done. I would simply liket o know, because then I have a real reason why to start looking into Go more seriously :-).

Bienlein

unread,
Jan 6, 2014, 11:07:40 AM1/6/14
to golan...@googlegroups.com, Bienlein, Abhijit Kadam, Didier Spezia


Am Montag, 6. Januar 2014 15:33:32 UTC+1 schrieb Dmitry Vyukov:
On Mon, Jan 6, 2014 at 6:02 PM, Bienlein <jet...@web.de> wrote:
>
...

Also a driver could use a single thread for IO and park/unpark user
goroutines on channels. That would have the same effect.

Is there some description somewhere how this park/unpark works? That would be really interesting ;-).

Thanks, Bienlein

Abhijit Kadam

unread,
Jan 6, 2014, 11:25:15 AM1/6/14
to Bienlein, golan...@googlegroups.com, Didier Spezia
Non blocking IO can can be done in other languages/runtimes like java however the implementation is difficult with callbacks (although callbacks are natural in nodejs). Recently .net and java have tried to make async simple in servers by having async controller/servlets however still not as clean as serial code. The intent is to keep a thread not being blocked and instead serve as many requests as possible. 

With golang the go routines have small stack size, they are light hence can there can be thousands of them and are executed by the runtime scheduler so the user does not create os threads or use directly os threads. If all IO is async then golang has best of both worlds with simple style of code.

Dmitry Vyukov

unread,
Jan 6, 2014, 12:39:08 PM1/6/14
to Bienlein, golang-nuts, Abhijit Kadam, Didier Spezia
park0() parks goroutine gp:
https://code.google.com/p/go/source/browse/src/pkg/runtime/proc.c#1347

runtime·ready() unparks goroutine gp (makes it runnable again):
https://code.google.com/p/go/source/browse/src/pkg/runtime/proc.c#333

Abhijit Kadam

unread,
Jan 6, 2014, 1:24:25 PM1/6/14
to golan...@googlegroups.com, Bienlein, Abhijit Kadam, Didier Spezia
Many thanks Dmitry and all. Good thing is in future when runtime improves then users would just have to recompile the code.
Reply all
Reply to author
Forward
0 new messages