القنوات
Channels
مفهوم
~22 دقيقة
القنوات — Channels
القنوات هي الطريقة الرسمية للتواصل بين goroutines في Go. تخيّلها كأنابيب: goroutine واحد يُرسل قيمة من طرف، و goroutine آخر يستقبلها من الطرف الآخر.
القنوات تحل مشكلتين:
- التواصل — تمرير البيانات بين goroutines
- التزامن — ضمان ترتيب العمليات
إنشاء قناة واستخدامها
main.go
Output:
كيف تعمل القناة غير المُخزّنة — Unbuffered Channel
القناة غير المُخزّنة (الافتراضية) تعمل كنقطة تسليم مباشرة:
- المُرسل ينتظر حتى يكون هناك مُستقبل
- المُستقبل ينتظر حتى يكون هناك مُرسل
- يتم التبادل في نفس اللحظة — هذا يُسمى synchronization
main.go
Output:
القنوات المُخزّنة — Buffered Channels
القناة المُخزّنة لها سعة — المُرسل لا ينتظر إلا إذا امتلأت القناة:
main.go
Output:
متى تستخدم كل نوع؟
| النوع | متى |
|---|---|
| غير مُخزّن | تريد تزامناً مضموناً (تسليم مباشر) |
| مُخزّن | تريد فصل المُرسل عن المُستقبل (مثل قائمة مهام) |
التكرار على قناة — Range over Channel
main.go
Output:
قواعد الإغلاق:
- فقط المُرسل يغلق القناة — أبداً المُستقبل
- الإرسال لقناة مغلقة يسبب panic
- الاستقبال من قناة مغلقة يُرجع القيمة الصفرية فوراً
اتجاه القناة — Channel Direction
يمكنك تحديد اتجاه القناة في معاملات الدوال لزيادة الأمان:
main.go
Output:
⚠️ الجمود — Deadlock
الجمود يحدث عندما ينتظر الجميع ولا أحد يعمل:
// ❌ جمود! main ينتظر ولا أحد يُرسل
ch := make(chan int)
<-ch // deadlock!
// ❌ جمود! main يُرسل ولا أحد يستقبل (قناة غير مُخزّنة)
ch := make(chan int)
ch <- 42 // deadlock!
Go يكتشف الجمود ويُوقف البرنامج برسالة: fatal error: all goroutines are asleep - deadlock!
نمط عملي: خط أنابيب — Pipeline Pattern
main.go
Output:
تحدي — Challenge
أنشئ goroutine يُرسل مربعات الأرقام 1-10 عبر قناة، واستقبلها واجمعها في main