runtime.LockOSThread() question

284 views
Skip to first unread message

SrimanthG

unread,
Oct 3, 2016, 2:49:31 PM10/3/16
to golang-nuts
Hello,
I ran a Go program with GOMAXPROCS=1 and two goroutines which both did "runtime.LockOSThread()" and slept 10 seconds before exiting.


Since I had 1 OS thread and 2 goroutines trying to lock an OS thread, I was expecting only one of them to complete first before the other one started... because the documentation said "Until the calling goroutine exits or calls UnlockOSThread, it will always execute in that thread, and no other goroutine can."

However the output shows that both goroutines execute in parallel, contradicting LockOSThread documentation.
Can someone explain if the documentation is wrong, if its a bug, or a better way to understand how these constructs work?
Regards,
Srimanth

Ian Lance Taylor

unread,
Oct 3, 2016, 3:04:39 PM10/3/16
to SrimanthG, golang-nuts
GOMAXPROCS set a limit on the number of goroutines that may run in
parallel. It does not set any sort of limit on the number of threads
that may exist. You have two threads, which is fine. All that
setting GOMAXPROCS=1 does is request the scheduler to only run one of
those threads at a time.

Ian

SrimanthG

unread,
Oct 3, 2016, 3:10:14 PM10/3/16
to golang-nuts, srimanth...@blippar.com
If you run the code snippet I pasted in https://play.golang.org/p/4R-WlCiKNT you will see that it runs both in parallel - hence my confusion

Ian Lance Taylor

unread,
Oct 3, 2016, 3:15:18 PM10/3/16
to SrimanthG, golang-nuts
On Mon, Oct 3, 2016 at 12:10 PM, 'SrimanthG' via golang-nuts
<golan...@googlegroups.com> wrote:
> If you run the code snippet I pasted in https://play.golang.org/p/4R-WlCiKNT
> you will see that it runs both in parallel - hence my confusion

Sleeping in time.Sleep does not count as running.

If you mean something else, can you be more specific? My apologies if
I'm missing something.

Ian
> --
> 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
> email to golang-nuts...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

SrimanthG

unread,
Oct 3, 2016, 3:24:09 PM10/3/16
to golang-nuts, srimanth...@blippar.com
Thank you for pointing that out. 

Do you mean to say that as long as the process is running instructions, it will not let any other goroutine use that OS thread and execute?
If so, can the documentation be updated to mention sleeping as cause for letting other goroutines in.

Also, what other calls can result in other goroutines being used? Would a network call waiting for IO result in a goroutine context switch?

Thanks in advance.

SrimanthG

unread,
Oct 3, 2016, 3:48:04 PM10/3/16
to golang-nuts, srimanth...@blippar.com
I have another code snippet which hits the same problem and it does not use sleep: https://play.golang.org/p/mUPCOFle4h
All 10 goroutines are going beyond "runtime.LockOSThread()" on a single OS thread.

Output:
main
locked 1
locked 10
locked 9
locked 8
locked 7
locked 6
locked 5
locked 4
locked 3
locked 2
done 1
done 6
done 4
done 8
done 7
done 2
done 9
done 5
done 3
done 10


Thank you very much for looking into this.

Ian Lance Taylor

unread,
Oct 3, 2016, 4:28:41 PM10/3/16
to SrimanthG, golang-nuts
On Mon, Oct 3, 2016 at 12:24 PM, 'SrimanthG' via golang-nuts
<golan...@googlegroups.com> wrote:
>
> Do you mean to say that as long as the process is running instructions, it
> will not let any other goroutine use that OS thread and execute?

It's either somewhat simpler or much more complex than that. It is
simpler in the sense that while runtime.LockOSThread is in effect, no
other goroutine will be able to run on that thread. It is more
complex in that this does not in any way imply that no other goroutine
will be able to run. The Go scheduler multiplexes goroutines onto
threads. While runtime.LockOSThread is in effect, the scheduler will
not put any other goroutine on that thread. But it will still happily
run goroutines on other threads.

> If so, can the documentation be updated to mention sleeping as cause for
> letting other goroutines in.

Give the above, i don't think that would be useful.

it sounds like you want to ensure that part of your program executes
by itself, with no other code running in parallel. That is not the
problem that runtime.LockOSThread solves. LockOSThread is for a
completely different problem: ensuring coordination between Go code
and C code, when the C code uses thread-local storage and therefore
expects to always be run on the same thread. To ensure that code
executes by itself, use the facilities in the sync package.

> Also, what other calls can result in other goroutines being used? Would a
> network call waiting for IO result in a goroutine context switch?

Yes. Among many other things.

Ian

Ian Lance Taylor

unread,
Oct 3, 2016, 4:33:08 PM10/3/16
to SrimanthG, golang-nuts
On Mon, Oct 3, 2016 at 12:48 PM, 'SrimanthG' via golang-nuts
<golan...@googlegroups.com> wrote:
> I have another code snippet which hits the same problem and it does not use
> sleep: https://play.golang.org/p/mUPCOFle4h
> All 10 goroutines are going beyond "runtime.LockOSThread()" on a single OS
> thread.

No, they are not. What is happening is that the 10 different
goroutines are running on 10 different OS threads. And furthermore
only one of those OS threads is running at one time. But there is
nothing to prevent the goroutine scheduler from flipping back and
forth between which goroutine, and therefore which thread, will run.
The goroutine scheduler is able to preempt any goroutine at a function
call point (among many other places that a goroutine can be
preempted).

Ian

Srimanth Gunturi

unread,
Oct 3, 2016, 4:45:19 PM10/3/16
to Ian Lance Taylor, golang-nuts
Now it is making more sense. 
So GOMAXPROCS has no connection with the actual number of OS threads created to run goroutines. But it does determine how many of them are active at any given time. 
Also, a single OS thread can multiplex multiple goroutines, unless #LockOSThread() is invoked in which case that OS thread will exclusively run that goroutine to completion.

Thank you for explaining.

Reply all
Reply to author
Forward
0 new messages