If you haven't studied concurrency before, I can't recommend any tutorials.
To start to learn about concurrency, I'd first recommend _some_
reading and theoretical background.

Concurrency is a complex concept. A "10x" multiplier estimation
compared to e.g. structured programming is probably right, definitely
not a 2x and probably not a 100x. Don't expect to become _proficient_
in concurrent programming in a couple of hours. Probably you won't be
able to download a couple of examples and start tinkering with them
successfully.

A good start is maybe:
https://golang.org/doc/faq#csp

Then maybe this:
https://en.wikipedia.org/wiki/Communicating_sequential_processes

The book is available for free:
http://www.usingcsp.com/cspbook.pdf

Don't expect to absorb the whole book in a couple of hours, it might
take from a couple of weeks to a few month to start to see how much
you still don't know.

As soon as you get a general understanding of concurrent concepts,
you'll most probably find adequate tutorials for yourself.

(To add to what Jan asked: for sharing code on golang-nuts please
share links to play.golang.org.)


On 3/1/19, mountain...@gmail.com <mountain...@gmail.com> wrote:
> Is there a recommended tutorial?
>
> 在 2019年3月1日星期五 UTC+8下午12:21:58,Robert Engels写道:
>>
>> I think it would be helpful if you learned more about concurrent
>> programming. It is 10x harder, even with the simplifications that Go
>> offers. If you don’t understand the concepts you are going to struggle.
>> Start with some tutorials and work your way up.
>>
>> On Feb 28, 2019, at 10:14 PM, mount...@gmail.com <javascript:> wrote:
>>
>> This is the stack information printed when blocking, how to see which G
>> blocking program?
>>
>> SIGABRT: abort
>> PC=0x7fff9ceabbf2 m=0 sigcode=0
>>
>> goroutine 0 [idle]:
>> runtime.pthread_cond_wait(0x1967620, 0x19675e0, 0x7fff00000000)
>>         /usr/local/go/src/runtime/sys_darwin.go:302 +0x51
>> runtime.semasleep(0xffffffffffffffff, 0x7fff5fbff670)
>>         /usr/local/go/src/runtime/os_darwin.go:63 +0x85
>> runtime.notesleep(0x19673e0)
>>         /usr/local/go/src/runtime/lock_sema.go:167 +0xe3
>> runtime.stoplockedm()
>>         /usr/local/go/src/runtime/proc.go:2165 +0x8a
>> runtime.schedule()
>>         /usr/local/go/src/runtime/proc.go:2565 +0x2d9
>> runtime.park_m(0xc000072480)
>>         /usr/local/go/src/runtime/proc.go:2676 +0xae
>> runtime.mcall(0x105722b)
>>         /usr/local/go/src/runtime/asm_amd64.s:299 +0x5b
>>
>> goroutine 1 [semacquire]:
>> sync.runtime_Semacquire(0xc000027794)
>>         /usr/local/go/src/runtime/sema.go:56 +0x39
>> sync.(*WaitGroup).Wait(0xc000027794)
>>         /usr/local/go/src/sync/waitgroup.go:130 +0x64
>> cmd/go/internal/work.(*Builder).Do(0xc00023b0e0, 0xc0003ee3c0)
>>         /usr/local/go/src/cmd/go/internal/work/exec.go:174 +0x38e
>> cmd/go/internal/run.runRun(0x195c300, 0xc00001e0e0, 0x1, 0x1)
>>         /usr/local/go/src/cmd/go/internal/run/run.go:137 +0x55b
>> main.main()
>>         /usr/local/go/src/cmd/go/main.go:219 +0x7d4
>>
>> goroutine 5 [syscall]:
>> os/signal.signal_recv(0x0)
>>         /usr/local/go/src/runtime/sigqueue.go:139 +0x9f
>> os/signal.loop()
>>         /usr/local/go/src/os/signal/signal_unix.go:23 +0x22
>> created by os/signal.init.0
>>         /usr/local/go/src/os/signal/signal_unix.go:29 +0x41
>>
>> goroutine 50 [select]:
>> cmd/go/internal/work.(*Builder).Do.func2(0xc000027794, 0xc00023b0e0,
>> 0xc0004b0620)
>>         /usr/local/go/src/cmd/go/internal/work/exec.go:155 +0x12f
>> created by cmd/go/internal/work.(*Builder).Do
>>         /usr/local/go/src/cmd/go/internal/work/exec.go:152 +0x36a
>>
>> goroutine 51 [select]:
>> cmd/go/internal/work.(*Builder).Do.func2(0xc000027794, 0xc00023b0e0,
>> 0xc0004b0620)
>>         /usr/local/go/src/cmd/go/internal/work/exec.go:155 +0x12f
>> created by cmd/go/internal/work.(*Builder).Do
>>         /usr/local/go/src/cmd/go/internal/work/exec.go:152 +0x36a
>>
>> goroutine 52 [syscall]:
>> syscall.Syscall6(0x7, 0x12006, 0xc000050c24, 0x0, 0xc0002f43f0, 0x0, 0x0,
>>
>> 0xc0002f43f0, 0x0, 0xc0000e2400)
>>         /usr/local/go/src/syscall/asm_darwin_amd64.s:41 +0x5
>> syscall.wait4(0x12006, 0xc000050c24, 0x0, 0xc0002f43f0, 0x90, 0x1566d60,
>> 0x14cc401)
>>         /usr/local/go/src/syscall/zsyscall_darwin_amd64.go:34 +0x7b
>> syscall.Wait4(0x12006, 0xc000050c74, 0x0, 0xc0002f43f0, 0x0, 0x1, 0x1)
>>         /usr/local/go/src/syscall/syscall_bsd.go:129 +0x51
>> os.(*Process).wait(0xc0002fd4a0, 0xc000034a00, 0xc000050cf8, 0x0)
>>         /usr/local/go/src/os/exec_unix.go:38 +0x7b
>> os.(*Process).Wait(0xc0002fd4a0, 0x15b89c8, 0x15b89d0, 0x15b89c0)
>>         /usr/local/go/src/os/exec.go:125 +0x2b
>> os/exec.(*Cmd).Wait(0xc00052da20, 0x0, 0x0)
>>         /usr/local/go/src/os/exec/exec.go:465 +0x5b
>> os/exec.(*Cmd).Run(0xc00052da20, 0x50, 0xc0000df7c0)
>>         /usr/local/go/src/os/exec/exec.go:309 +0x5c
>> cmd/go/internal/base.RunStdin(0xc0000df7c0, 0x1, 0x1)
>>         /usr/local/go/src/cmd/go/internal/base/base.go:162 +0x11e
>> cmd/go/internal/run.buildRunProgram(0xc00023b0e0, 0xc0003ee3c0, 0x13999b3,
>>
>> 0xc00023b150)
>>         /usr/local/go/src/cmd/go/internal/run/run.go:151 +0x26d
>> cmd/go/internal/work.(*Builder).Do.func1(0xc0003ee3c0)
>>         /usr/local/go/src/cmd/go/internal/work/exec.go:107 +0x72
>> cmd/go/internal/work.(*Builder).Do.func2(0xc000027794, 0xc00023b0e0,
>> 0xc0004b0620)
>>         /usr/local/go/src/cmd/go/internal/work/exec.go:165 +0xbb
>> created by cmd/go/internal/work.(*Builder).Do
>>         /usr/local/go/src/cmd/go/internal/work/exec.go:152 +0x36a
>>
>> goroutine 53 [select]:
>> cmd/go/internal/work.(*Builder).Do.func2(0xc000027794, 0xc00023b0e0,
>> 0xc0004b0620)
>>         /usr/local/go/src/cmd/go/internal/work/exec.go:155 +0x12f
>> created by cmd/go/internal/work.(*Builder).Do
>>         /usr/local/go/src/cmd/go/internal/work/exec.go:152 +0x36a
>>
>> goroutine 24 [chan receive]:
>> cmd/go/internal/base.processSignals.func1(0xc000086f00)
>>         /usr/local/go/src/cmd/go/internal/base/signal.go:21 +0x34
>> created by cmd/go/internal/base.processSignals
>>         /usr/local/go/src/cmd/go/internal/base/signal.go:20 +0x93
>>
>> rax    0x104
>> rbx    0xea00
>> rcx    0x7fff5fbff488
>> rdx    0xea00
>> rdi    0x1967620
>> rsi    0xea010000eb00
>> rbp    0x7fff5fbff520
>> rsp    0x7fff5fbff488
>> r8     0x0
>> r9     0x60
>> r10    0x0
>> r11    0x202
>> r12    0x1967620
>> r13    0x16
>> r14    0x1
>> r15    0x7fffa5c9d3c0
>> rip    0x7fff9ceabbf2
>> rflags 0x203
>> cs     0x7
>> fs     0x0
>> gs     0x0
>>
>> 在 2019年2月28日星期四 UTC+8下午8:44:55,Sameer Ajmani写道:
>>>
>>> The deadlock happens because the channel is empty, so the receive
>>> operation blocks forever.
>>>
>>> The second version imports a package that may start new goroutines in its
>>>
>>> init functions. If so, those goroutines may not be deadlocked, but the
>>> main
>>> function is still blocked on the receive operation.
>>>
>>> It can be useful to send SIGQUIT to a blocked Go program to dump the
>>> goroutine stack traces to the terminal.
>>>
>>> S
>>>
>>> On Thu, Feb 28, 2019 at 4:19 AM <mount...@gmail.com> wrote:
>>>
>>>> dead lock:
>>>>
>>>> package main
>>>>
>>>> import (
>>>>     "fmt"
>>>>     // _ "github.com/go-sql-driver/mysql"
>>>> )
>>>>
>>>> func main() {
>>>>     c1 := make(chan int, 10)
>>>>     fmt.Println(<-c1)
>>>> }
>>>>
>>>>
>>>> block:
>>>>
>>>> package main
>>>>
>>>> import (
>>>>     "fmt"
>>>>
>>>>     _ "github.com/go-sql-driver/mysql"
>>>> )
>>>>
>>>> func main() {
>>>>     c1 := make(chan int, 10)
>>>>     fmt.Println(<-c1)
>>>> }
>>>>
>>>> --
>>>> 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.
>>>>
>>> --
>> 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 <javascript:>.
>> For more options, visit https://groups.google.com/d/optout.
>>
>>
>
> --
> 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+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to