English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Golang درس أساسي

Golang جمل التحكم

Golang وظائف & طرق

Golang بنية

Golang قطع & Arrays

Golang 字بات (String)

Golang إشارات

Golang واجهات

Golang متوازنة

Golang استثناء (Error)

Golang غير ذلك

جملة Go Select و deadlock deadlock

في لغة Go، جملة select تشبهجملة switch، ولكن في جملة select، تشير جملة case إلى عمليات التواصل، وهي عمليات إرسال أو استقبال من القنوات.

اللغة:

select{
    case SendOrReceive1: // جملة
    case SendOrReceive2: // جملة
    case SendOrReceive3: // جملة
    .......
    default: // جملة
 }

في هذا المقال، سنتعلم كيفية تجنب deadlock باستخدام الحالة الافتراضية. ولكن أولاً، دعونا نعرف ما هو deadlock؟

deadlock:عندما تحاول قراءة أو كتابة بيانات من قناة دون وجود قيمة في القناة. لذلك، يُحبط goroutine الحالي ويتم نقل التحكم إلى goroutine أخرى، ولكن إذا لم يكن هناك goroutine أخرى متاحة أو إذا كان لديها goroutine نائمة، فإن البرنامج سي崩溃. يُسمى هذا الظاهرة deadlock. كما هو موضح في المثال التالي:

package main
func main() {
    //إنشاء قناة
    //يحدث deadlock لأن لا يوجد goroutine يكتب
    //لذلك، تم توقيف جملة select للأبد
    c := make(chan int)
    select {
    case <-c:
    }
}

النتيجة:

خطأ حاسم: جميع goroutines نائمة - deadlock!
goroutine 1 [استقبال قناة]:
main.main()

لتفادي هذا، نستخدم حالة افتراضية في جملة select. بمعنى آخر، عند ظهور عائق في البرنامج، يتم تنفيذ الحالة الافتراضية في جملة select لتجنب العائق. كما هو موضح في المثال التالي، نستخدم حالة افتراضية في جملة select لتجنب العائق.

package main 
  
import "fmt"
  
func main() { 
  
    //إنشاء قناة
    c := make(chan int) 
    select { 
    case <-c: 
    default: 
        fmt.Println("!.. حالة افتراضية..!") 
    } 
}

النتيجة:

!.. حالة افتراضية..!

عندما يكون لدى جملة select قناة فارغة، يسمح أيضًا باستخدام الحالة الافتراضية. كما هو موضح في المثال التالي، القناة c فارغة، لذا يتم تنفيذ الحالة الافتراضية. إذا كانت الحالة الافتراضية غير متاحة هنا، فإن البرنامج سيكون متوقوفًا للأبد، مما يؤدي إلى ظهور عائق. يُعرف هذا الظاهرة بـ deadlock.

package main
import "fmt"
func main() {
    //إنشاء قناة
    var c chan int
    select {
    case x1 := <-c:
        fmt.Println("القيمة: ", x1)
    default:
        fmt.Println("حالة افتراضية..!")
    }
}

النتيجة:

حالة القياسية..!