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

Reply via email to