Golang Channel is Collection Type part 2

จากตอนที่แล้ว Unbuffer จะ block ไม่ว่าจะการรับ หรือการส่งข้อมูลไปที่ channel จนกว่าจะมีรับและส่งเกิดขึ้นแยกออกจากกันคนละ Goroutine ตอนนี้มาดูพฤติกรรมของ Channel แบบมี Buffer กันบ้าง

พฤติกรรมการทำงานของ Channel แบบ Buffer

Buffer คือที่เก็บข้อมูลของ Channel นั่นเองครับ เก็บเอาไว้ก่อน ก่อนที่จะมีใครมาดึงออกไปใช้นั่นเอง เพราะฉนั้นพฤติกรรมการ blocking ตอนส่งและตอนรับก็ต่างออกไปขึ้นอยู่กับจำนวน Buffer นั่นเอง ตัวอย่างเช่นถ้าเรามี buffer 1 ทำให้เห็นภาพโดยให้ buffer แทนกล่องใส่ของ

ch := make(chan int, 1) // one buffer of channel int
 ---
| |
---

ถ้าเราส่งของเข้า channel

ch <- 1
 ---
| 1 |
---

ข้อมูลนั่นจะถูกเอาไปพักไว้ใน buffer ของ channel ครับถ้ายังมี buffer ที่ว่างอยู่ให้เก็บ ดังนั้นเมื่อไหร่ที่ buffer ว่างให้เก็บ จะไม่เกิดการ blocking ที่บรรทัดการส่งนั้นๆครับ

ทีนี้ ถ้าเกิดเราส่งค่าเข้าไปอีก โดยที่ buffer เต็มแล้วละ แบบนี้

ch <- 1
 ---
| 1 |
---
ch <- 2

จะเกิดการ blocking ที่การส่ง ch <- 2 ครับเพราะไม่สามารถเอาข้อมูลเข้าไปเก็บใน buffer ได้จะค้างไว้จนกว่าจะเอาของเข้าไปใน buffer ได้

ทีนี้มาดูพฤติกรรมเวลาเอาของออกจาก channel ที่มี buffer กันบ้าง เช่น

 ---
| 1 |
---
val <- ch

ถ้าใน buffer ของ channel มีค่าเก็บอยู่ แล้วเราเอาของออกจาก channel จะไม่เกิดการ block ขึ้นครับ ก็ตรงๆง่ายๆ เมื่อมันมีของพร้อมเอาออกอยู่ใน buffer ก็ไม่ต้องค้างรอ แต่ว่าถ้าเกิดไม่มีข้อมูลสักค่าใน buffer ของ channel แบบนี้

 ---
| |
---
val <- ch

การเอาของออกจาก channel ที่ไม่มีข้อมูลสักค่าใน buffer แบบนี้จะค้างจนกว่าจะมีใครส่งข้อมูลเข้ามาเก็บไว้ใน channel ครับ

part 2 นี้น่าจะเห็นพฤติกรรมที่แตกต่างของ Channel ที่มี buffer กันไปแล้ว ตอนหน้าเดี๋ยวดูกรณีที่ channel เป็น nil และกรณีที่เราทำการ close channel นั้นไปแล้วกันครับ