On Saturday, April 7, 2018 at 9:04:38 AM UTC-4, T L wrote:
>
>
>
> On Saturday, April 7, 2018 at 8:39:22 AM UTC-4, Steven Hartland wrote:
>>
>> You should use a wait group to guarantee the behaviour of this.
>>
>
> I know there are other ways to do the task.
> I just feel the runtime behavior is some strange.
>
> The following is the code to receive a value if there are some goroutines
> are wariting in sending.
>
> func recv(c *hchan, sg *sudog, ep unsafe.Pointer, unlockf func()) {
> if c.dataqsiz == 0 {
> if raceenabled {
> racesync(c, sg)
> }
> if ep != nil {
> // copy data from sender
> recvDirect(c.elemtype, sg, ep)
> }
> } else {
> // Queue is full. Take the item at the
> // head of the queue. Make the sender enqueue
> // its item at the tail of the queue. Since the
> // queue is full, those are both the same slot.
> qp := chanbuf(c, c.recvx)
> if raceenabled {
> raceacquire(qp)
> racerelease(qp)
> raceacquireg(sg.g, qp)
> racereleaseg(sg.g, qp)
> }
> // copy data from queue to receiver
> if ep != nil {
> typedmemmove(c.elemtype, ep, qp)
> }
> // copy data from sender to queue
> typedmemmove(c.elemtype, qp, sg.elem)
> c.recvx++
> if c.recvx == c.dataqsiz {
> c.recvx = 0
> }
> c.sendx = c.recvx // c.sendx = (c.sendx+1) % c.dataqsiz
> }
> sg.elem = nil
> gp := sg.g
> unlockf()
> gp.param = unsafe.Pointer(sg)
> if sg.releasetime != 0 {
> sg.releasetime = cputicks()
> }
> goready(gp, 4)
> }
>
> From the code, we can find that the receive from the only buffer
> and the fill to the only buffer with the next queuing value
> are really in one atomic operation.
>
> But I don't know why two weeks ago, the behavior is not consistent with
> the code.
>
The only reason would be, if no bugs in code, in a very low possibility,
the 99 send goroutines haven't been ready to send yet when a receive is
finished.
>
>
>>
>> On Sat, 7 Apr 2018 at 12:54, T L <[email protected]> wrote:
>>
>>>
>>>
>>> On Monday, March 26, 2018 at 4:09:24 PM UTC-4, Marvin Renich wrote:
>>>>
>>>> It seems that you understand why you are seeing the behavior you
>>>> reported, but you are questioning whether the spec either does or
>>>> should
>>>> guarantee that reading from a channel with a goroutine waiting to send
>>>> on that channel will fill the buffer as an atomic part of the read.
>>>>
>>>> As others have said, the spec does not guarantee this. I would like to
>>>> add that I believe it shouldn't. Suppose goroutine A is currently
>>>> blocked waiting to send on a channel. Now goroutine B reads from that
>>>> channel. If the refill of the channel must happen atomically with the
>>>> read from that channel, now goroutine B must be put in a blocked state
>>>> waiting for goroutine A to finish its send. This contradicts the spec
>>>> at [1] which states
>>>>
>>>> ...communication succeeds without blocking if the buffer is not full
>>>> (sends) or not empty (receives).
>>>>
>>>> If you think about how this is likely to be implemented (including
>>>> considerations for GOMAXPROC and multicore vs single core systems), you
>>>> should realize that, while it would be possible to implement
>>>> atomic-refill, it would give no (or very little) benefit and might have
>>>> undesirable performance effects.
>>>>
>>>> As an aside, I think the reason Jake is seeing 100 lines of output and
>>>> you only see 1 is likely to be the difference between GOMAXPROC=1 and
>>>> greater than 1. If GOMAXPROC=1, the scheduler may force a running
>>>> goroutine to yield after receiving, but before returning from the
>>>> receive operation. In other words, the receive happens without
>>>> blocking, but the scheduler thinks that is a convenient point for
>>>> giving
>>>> another goroutine an opportunity to run.
>>>>
>>>
>>>
>>> No, I tried both GOMAXPROC=1 and GOMAXPROC=4. Same results.
>>>
>>> It is strange that I just tried it again, now there will be always 100
>>> lines outputted,
>>> for both GOMAXPROC=1 and GOMAXPROC=4, for both v1.10 and v1.10.1.
>>> Quite strange.
>>>
>>>
>>>>
>>>> ...Marvin
>>>>
>>>> [1] https://golang.org/ref/spec#Channel_types
>>>
>>>
>>>
>>>
>>> --
>>> 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 [email protected].
>>> 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 [email protected].
For more options, visit https://groups.google.com/d/optout.