Yes, and that’s why there is no guarantee about the ordering.
Based on the code you provided above, I’m guessing the producer code is something like this:
go func() {
....
p.logCh <- process
// it's actually possible that another goroutine send another
// process to p.logCh in different goroutine after the line above
// and before the log.Printf line below
log.Printf("<the_timestamp> <the_process_id> sent")
....
}
So, it’s possible that the flow of your program is something like this:
- in 1st nanosecond you created 2 goroutine, goroutine A and goroutine B
- in 2nd nanosecond, goroutine A send an item X to the channel
- in 3rd nanosecond, goroutine B send an item Y to the channel
- in 4th nanosecond, goroutine B log “4 Y ended and sent to channel”
- in 5th nanosecond, goroutine A log “5 X ended and sent to channel”
as a result, you will see that Y logged before X, but actually X is sent first before Y.
What’s the solution? Well, you should think that sending an item to a channel and logging the event as a single operation that should be atomic (can’t be overlapped with other operation). One way to do this is using mutex. Before sending an item to a channel, lock the mutex first, then log the event, then unlock the mutex.