There is one go routine generating data. Also are many go routines that handles http response. I want generated data to be passed to all http handler routines. All dispatched data are same.
I thought two solutions. Using channel pipeline to fan-out or using mutex and condition variable.
I concern if former way needs memory allocation to put data in channel.
What should I choose?
Your use case sounds like it benefits from channels. In general channels are preferred when communication between go routines is needed. Sounds like a classic example of a worker pool.
Mutexes are used to protect a piece of memory, so only 1 goroutine can access/modify it at a time. Often times this is the opposite of what people want, which is to parallelize execution.
A good rule of thumb is to not worry about optimization(memory allocation or not) until it actually becomes an issue. Premature optimization is a common anti-pattern.
On one job interview I had to answer this question - which advantages do you have owing to use epoll integration/implementation in Go.
I just know what can do epoll and that complexity for any descriptors count is O(1), but have no idea why Go is better than other languages.
I found this branch https://news.ycombinator.com/item?id=15624586 and guy say that reason, maybe, that Go don't use stack switching. It's hard to understand for me. Which part of program don't use stack switching? Every goroutine has his own stack.
That's not the netpoller integration per se which makes Go strong in its field—it's rather the way that integration is done: instead of being bolted-on as a library, in Go, the netpoller is tightly integrated right into the runtime and the scheduler (which decides which goroutine to run, and when).
The coupling of super-light-weight threads of execution—goroutines—with the netpoller allows for callback-free programming. That is, once your service gets another client connected, you just hand this connection to a goroutine which merely reads the data from it (and writes its response stream to it). As soon as there's no data available when the goroutine wants to read it, the scheduler suspends the goroutine and unblocks it once the netpoller reports there's data available; the same happens when the goroutine wants to write data but the sending buffer is full.
To recap, the netpoller in Go is intertwined with the goroutine scheduler which allows goroutines transparently wait for data availability without requiring the programmer to explicitly code the event loop and callbacks or deal with "futures" and "promises" which are mere callbacks wrapped in pretty objects.
I invite you to read this classic essay which explains this stuff with much more beautiful words.
Consider such situation. There are one main goroutine and ten subsidiary
goroutines. All of them have access to channel. Main one sends 1000 numbers to this channel and subsidiary ones will read from it.
Is there any guarantee that each subsidiary goroutine will read exactly 100 numbers or this amount may vary like some goroutine will read 99 numbers and another 101?
No, there is no guarantee, because it depends on the runtime of every goroutine and that depends on how well the goroutines are distributed across the CPU.
With goroutine scheduling via an unbuffered channel, then interesting thing to note is that the channel serves purely as a blocking mechanism - in that the value is never "sent into the channel" and nothing actually "reads from" it.
An unbuffered channel works purely as a synchronization mechanism: for the goroutine sending on a channel, it works more along the lines of "sleep until some goroutine is ready to receive" and for the receiving goroutine it's "sleep until some goroutine is ready to send".
This should make it clear that sends and receives have no kind of fairness or distribution system built in - they're purely first come first served, or possibly even more arbitrary depending on the scheduler's current load.
If I am using channels properly, should I need to use mutexes to protect against concurrent access?
You don't need mutex if you use channels correctly. In some cases a solution with mutex might be simpler though.
Just make sure the variable(s) holding the channel values are properly initialized before multiple goroutines try to access the channel variables. Once this is done, accessing the channels (e.g. sending values to or receiving values from them) is safe by design.
Supporting documents with references (emphases added by me):
Spec: Channel types:
A single channel may be used in send statements, receive operations, and calls to the built-in functions cap and len by any number of goroutines without further synchronization. Channels act as first-in-first-out queues. For example, if one goroutine sends values on a channel and a second goroutine receives them, the values are received in the order sent.
Effective Go: Concurrency: Share by communicating
Concurrent programming in many environments is made difficult by the subtleties required to implement correct access to shared variables. Go encourages a different approach in which shared values are passed around on channels and, in fact, never actively shared by separate threads of execution. Only one goroutine has access to the value at any given time. Data races cannot occur, by design. To encourage this way of thinking we have reduced it to a slogan:
Do not communicate by sharing memory; instead, share memory by communicating.
This approach can be taken too far. Reference counts may be best done by putting a mutex around an integer variable, for instance. But as a high-level approach, using channels to control access makes it easier to write clear, correct programs.
This article is also very helpful: The Go Memory Model
Also quoting from the package doc of sync:
Package sync provides basic synchronization primitives such as mutual exclusion locks. Other than the Once and WaitGroup types, most are intended for use by low-level library routines. Higher-level synchronization is better done via channels and communication.
In order to assess whether go is a possible option for an audio/video application, I would like to know whether message passing in go satisfies any non-blocking progress guarantees (being obstruction-free, lock-free or wait-free). In particular, the following scenarios are relevant:
Single producer single consumer:
Two threads communicate using a shared channel. Thread A only does asynchronous sends, thread B only does asynchronous receives. Suppose the OS scheduler decides to interrupt thread A at the "worst possible moment" for an indefinite amount of time. Is thread B guaranteed to finish a receive operation in a bounded number of cpu cycles or is there a (theoretical) possibility that thread A can put the channel into a state where thread B needs to wait for the OS to resume thread A?
Multiple producers:
Several threads A1, A2, A3, ... communicate with one or more others threads using a shared channel. The threads Ai only do asynchronous sends. Suppose A2, A3, ... are suspended by the OS scheduler at the "worst possible moment" for an indefinite amount of time. Is thread A1 still guaranteed to finish a send operation in a bounded number of cpu cycles? Suppose further that each thread only wants to do one send. If the program is run sufficiently long (with a "malicious" scheduler which potentially starves some threads or interrupts and resumes threads at the "worst possible moment"), is at least one send guaranteed to succeed?
I am not so much interested in typical scenarios here, but rather worst-case guarantees.
See Non-blocking algorithm (Wikipedia) for more details on obstruction-, lock- and wait-free algorithms.
Normal sends and receives are blocking operations by definition. You can do a non-blocking send or receive by using a select statement:
select {
case ch <- msg:
default:
}
(Receiving is very similar; just replace the case statement.)
The send only takes place when there is room in the channel's buffer. Otherwise the default case runs. Note that internally a mutex is still used (if I'm reading the code correctly).
The Go Memory Model doesn't require sends and receives to be non-blocking, and the current runtime implementation locks the channel for send and recv. This means, for instance, that it is possible to starve a sending or receiving go-routine if the OS-scheduler interrupts another thread running another go-routine which tries to send or receive on the same channel while it has already acquired the channel's lock.
So the answer is unfortunately no :(
(unless someone reimplement parts of the runtime using non-blocking algorithms).
You're asking whether an operation is guarantee to complete within a bounded number of cycles, which of course is not a design consideration for this language (or most underlying OSes).
If run in a single thread, then Go uses cooperative multitasking between goroutines. So if one routine never yields, then the other will never run. If your program runs on multiple threads (as set by GOMAXPROCS), then you can run several goroutines simultaneously, in which case the OS controls scheduling between the threads. However, in neither case is there a guaranteed upper bound on the time to completion for a function call.
Note that the cooperative nature of goroutines gives you some amount of control over scheduling execution -- that is, routines are never preempted. Until you yield, you retain control of the thread.
As for blocking behavior, see The language specification:
The capacity, in number of elements, sets the size of the buffer in the channel. If the capacity is greater than zero, the channel is asynchronous: communication operations succeed without blocking if the buffer is not full (sends) or not empty (receives), and elements are received in the order they are sent. If the capacity is zero or absent, the communication succeeds only when both a sender and receiver are ready.
Note that non-blocking sends and receives on channels can be accomplished using the select syntax already mentioned.
Goroutines do not own channels or the values sent on them. So, the execution status of a goroutine that has sent / is sending values on a channel has no impact on the ability of other goroutines to send or receive values on that channel, unless the channel's buffer is full, in which case all sends will block until a corresponding receive occurs, or the buffer is empty, in which case all receives will block until there is a corresponding send.
Because goroutines use cooperative scheduling (they have to yield to the scheduler, either through a channel operation, a syscall, or an explicit call to runtime.Gosched()), it is impossible for a goroutine to be interrupted at the "worst possible time". It is possible for a goroutine to never yield, in which case, it could tie up a thread indefinitely. If you have only one thread of execution, then your other goroutines will never be scheduled. It is possible, but statistically improbable, for a goroutine to just never be scheduled. However, if all goroutines but one are blocked on sends or receives, then the remaining goroutine must be scheduled.
It is possible to get a deadlock. If I have two goroutines executing:
func Goroutine(ch1, ch2 chan int) {
i := <-ch1
ch2 <- i
}
...
ch1, ch2 := make(chan int), make(chan int)
go Goroutine(ch1, ch2)
go Goroutine(ch2, ch1)
Then, as should be apparent, both goroutines are waiting for the other to send a value, which will never happen.