How to signal(sigint) blocking goroutine

368 views
Skip to first unread message

natea...@gmail.com

unread,
Aug 7, 2018, 11:59:48 PM8/7/18
to golang-nuts
https://play.golang.org/p/d5n9bYmya3r

I'm new to the go language and trying to figure out how to sigint a blocking goroutine.  in the playground code I included an infinite for loop to simulate the blocking. In my real world use the for block would be a long running file save from an external device.  I appreciate any advice or direction that is given.

Thanks.

Ian Lance Taylor

unread,
Aug 8, 2018, 12:20:11 AM8/8/18
to natea...@gmail.com, golang-nuts
I'm not sure quite what you mean, but in general you can not send a
signal to a goroutine in Go. Goroutines are not threads. If you want
a goroutine to be interruptible, you must write the goroutine to check
whether something is trying to interrupt it; the standard library's
"context" package is often used for this purpose.

Ian

natea...@gmail.com

unread,
Aug 8, 2018, 6:56:32 PM8/8/18
to golang-nuts
Thanks for the info.  I will look at the context information.

gary.wi...@victoriaplumb.com

unread,
Aug 9, 2018, 11:06:37 AM8/9/18
to golang-nuts
Just re-organise the code a bit, try this:  https://play.golang.org/p/GMpfZlCNP9G

gary.wi...@victoriaplumb.com

unread,
Aug 9, 2018, 11:12:21 AM8/9/18
to golang-nuts
See this blog post for more interesting ways to handle goroutine communication and synchronization:



On Wednesday, 8 August 2018 04:59:48 UTC+1, natea...@gmail.com wrote:

natea...@gmail.com

unread,
Aug 9, 2018, 9:51:53 PM8/9/18
to golang-nuts
https://play.golang.org/p/mr58JS4WsJV

Okay, I realize now that I didn't do a very good job in my first post of explaining my problem, so I'll trying again.  In the above code I need to signal(sigint or sigterm) the exec.CommandContext on line 69 that is blocking so it will stop and finish the goroutine.  The goal behind the code is to set a record duration and then stop the blocking command after the record timer has been met and exit the goroutine normally.  So far I haven't been able to figure out how to signal the command to stop.  I have two tuners that can be recording a the same time, so I need them running in goroutines so the main thread can do other things.  I read through the context package that you recommended, but still can't get it to work. 

Thanks


On Wednesday, August 8, 2018 at 12:20:11 AM UTC-4, Ian Lance Taylor wrote:

Ian Lance Taylor

unread,
Aug 10, 2018, 12:02:01 AM8/10/18
to natea...@gmail.com, golang-nuts
On Thu, Aug 9, 2018 at 6:51 PM, <natea...@gmail.com> wrote:
>
> https://play.golang.org/p/mr58JS4WsJV
>
> Okay, I realize now that I didn't do a very good job in my first post of
> explaining my problem, so I'll trying again. In the above code I need to
> signal(sigint or sigterm) the exec.CommandContext on line 69 that is
> blocking so it will stop and finish the goroutine. The goal behind the code
> is to set a record duration and then stop the blocking command after the
> record timer has been met and exit the goroutine normally. So far I haven't
> been able to figure out how to signal the command to stop. I have two
> tuners that can be recording a the same time, so I need them running in
> goroutines so the main thread can do other things. I read through the
> context package that you recommended, but still can't get it to work.

The first step is to get the idea of signals out of your head. As I
said, you can not send a signal to a goroutine. It's the wrong
approach.

Instead, create a context.Context value (e.g., context.Background),
then pass it to context.WithTimeout or context.WithCancel, then pass
the Context to your goroutine. Have your function periodically check
whether context.Err is set. In some cases this is naturally done by
selecting on context.Done along with other channels, in some cases you
need to call context.Err every so often. When you want the goroutine
to stop, call the cancel function returned by WithTimeout or
WithCancel.

For more information, see https://blog.golang.org/context .

Ian



> On Wednesday, August 8, 2018 at 12:20:11 AM UTC-4, Ian Lance Taylor wrote:
>>
>> On Tue, Aug 7, 2018 at 7:02 PM, <natea...@gmail.com> wrote:
>> >
>> > https://play.golang.org/p/d5n9bYmya3r
>> >
>> > I'm new to the go language and trying to figure out how to sigint a
>> > blocking
>> > goroutine. in the playground code I included an infinite for loop to
>> > simulate the blocking. In my real world use the for block would be a
>> > long
>> > running file save from an external device. I appreciate any advice or
>> > direction that is given.
>>
>> I'm not sure quite what you mean, but in general you can not send a
>> signal to a goroutine in Go. Goroutines are not threads. If you want
>> a goroutine to be interruptible, you must write the goroutine to check
>> whether something is trying to interrupt it; the standard library's
>> "context" package is often used for this purpose.
>>
>> 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.

Tamás Gulácsi

unread,
Aug 10, 2018, 8:15:49 AM8/10/18
to golang-nuts
Juct use the same context to your ExecContexts and cancel it on success to make the other stop.

Space A.

unread,
Aug 10, 2018, 8:37:41 PM8/10/18
to golang-nuts
The first step is to get the idea of signals out of your head.  As I
said, you can not send a signal to a goroutine.  It's the wrong
approach.

Instead, create a context.Context value (e.g., context.Background)...


Hmm... Do not communicate by sharing memory; instead, share memory by communicating.


Regards



пятница, 10 августа 2018 г., 7:02:01 UTC+3 пользователь Ian Lance Taylor написал:

natea...@gmail.com

unread,
Aug 10, 2018, 10:54:08 PM8/10/18
to golang-nuts
Thanks for all the comments.  I did finally figure it out.  https://play.golang.org/p/ghCT6DCDLJz

On lines 69-70 changed that code from and exec.Command to exec.Start allowing me to sleep for the desired amount of time and then signal(sigint) the command via cmd.Process.Signal(syscall.SIGINT) 

Nate

Dave Cheney

unread,
Aug 10, 2018, 11:46:03 PM8/10/18
to golang-nuts
The context value you pass into record isn't used and running record in its own goroutine doesn't really add anything because the main goroutine just waits for the other goroutine to exit. The exit the second goroutine will be at least 1 second, but could be much longer.
Reply all
Reply to author
Forward
0 new messages