What can Go chan do that a list cannot?

I want to know in which situation Go chan makes code much simpler than using list or queue or array that is usually available in all languages.

As it was stated by Rob Pike in one of his speeches about Go lexer, Go channels help to organize data flow between structures that are not homomorphic.

I am interested in a simple Go code sample with chan that becomes MUCH more complicated in another language (for example C#) where chan is not available.

I am not interested in samples that use chan just to increase performance by avoiding waiting of data between generating list and consuming the list (which can be solved by chunking) or as a way to organize thread safe queue or thread-safe communication (which can be easily solved by locking primitives).

I am interested in a sample that makes code simpler structurally disregarding size of data.

If such sample does not exist then sample where size of data matters.

I guess desired sample would contain bi-directional communication between generator and consumer.

Also if someone could add tag [channel] to the list of available tags, that would be great.

A generic queue or array is generally not, by itself, thread safe, just like many other data types. Thread safety is usually accomplished in two ways:

  • Using mutex locks – each thread that wants to modify a value has to wait.
  • Delegation – only the owning thread can modify the value.

Mutex locks are fairly straight forward – nobody owns the value, but only one thread can modify it at a time. When one thread is modifying a value, other threads have to wait. The problem with this approach is contention. More than one thread wanting to modify a value at the same time, and the number of threads waiting stacks up.

How delegation is handled is really dependent on the language in question. In Objective C you have GCD to dispatch asynchronous (or even synchronous) requests on the owning thread. You have an opportunity to (asynchronously) have the value modified without holding up the requesting thread. GCD internally schedules these tasks into a queue and executes them when the target thread isn’t busy.

Go channels are somewhat a form of delegation. You can use it as a non-blocking queue by using buffered channels. But the biggest difference between Go channels and other approaches can probably be summed up with the following sentence:

Don’t communicate by sharing, share by communicating.

A Go channel is much more than just a queue, it’s a communication pipeline. The best way I can illustrate this is by showing an excerpt from one of my own projects:

for {
    select {
    case client := <-server.accept:
        server.addClient(client)
        go server.serveClient(client)
    case client := <-server.remove:
        server.removeClient(client)
    case envelope := <-server.dropbox:
        switch envelope.cmd {
        case "pub":
            server.publish(envelope)
        case "sub":
            server.subscribe(envelope)
        case "unsub":
            server.unsubscribe(envelope)
        }
    case err := <-server.errors:
        return err
    }
}

The above code is running on the main Go routine (the channels are buffered).

<-server.accept – A second Go routine (not shown here) handles new connections and passes them to the accept channel. The main Go routine accepts the new client and adds them to a map of connected clients. Another Go routine is spawned to handle requests from the new client.

<-server.remove – When a client disconnects the Go routine handling its connection passes it back to the main Go routine to be removed.

<-server.dropbox – When a client has something it wants to send it puts it into the “dropbox” to be delivered to other clients, which are registered in the map.

Each client has an inbox channel which the main thread can deliver “mail” to. The Go routine handling the client connection reads the inbox.

As you can see by the example, the code becomes somewhat relatable: A post-office with a drop box to deliver mail, and an inbox for each client to receive it. This is just one example of how channels can be used.

Should channels always be used in every situation? No – I have seen situations where a mutex lock made more sense than a channel. Atomic data structures is an example where mutex locks make more sense.

I think the overall goal of a channel is to make code easier to understand. It conveys intention more precisely, in certain (but many) situations. Internally a channel probably uses mutex locks. I think an important point to take home is – channels are useful; just don’t get carried away.

I want to know in which situation Go chan makes code much simpler than using list or queue or array that is usually available in all languages.

Let’s say you have a routine that generates Fibonacci numbers (as a stand-in for something more complex). The main routine needs to “get the next number” when it needs it. The main routine should not be coupled to the Fibonacci routine, so it must not store the Fibonacci state.

So where do you store the Fibonacci state in between calls? In a language without threads/coroutines, you would have to write a lot of extra code to store this state, and that storage code would have to be changed every time you need to store slightly different state. That “store the state” code is brittle and has nothing to do with the actual calculation.

So it’s much simpler to spin that routine off into it’s own thread of execution. (real thread of language thread). Then we can ask it to generate the next value when needed and neither side worries about state. Yay.

You can use Arrays for this communication, but you will need to write a bunch of code: Locking the array (to prevent races), handling the “array full” case, handling the array wrap-around case, handling the array underflow case, etc. A queue is more similar, but doesn’t have all the same semantics (not always mutithread safe, doesn’t always wake up the receiver, etc)

Having a channel makes it 100 times more obvious what you are doing. Once you get used to channels, you will use them all the time. Not having channels is like not having a Map/Dictonary/Hash data structure. People survived for many years without them, but once you have them, you see all kinds of places they are useful. You’ll start organizing your code around the CSP concept.

Gone are the days where you can buy a single-core computer (or even a single-core phone.) Therefore, communication between threads/processes is only going to get more important over time. If you (or your language) can only think in terms of single-CPU processing, you will be a dinosaur.

Concurrency is not parallelism, it’s better.

Channels and lists used a queues are very similar. In go, channels are designed to work with goroutines. Goroutines allows your program to utilize all the core of your computer. Channels allow the goroutines to share data safely across cores. Channels also allows goroutines to synchronize with the data.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật