CodeGym /Kurslar /C# SELF /Thread prioritetləri və thread növləri

Thread prioritetləri və thread növləri

C# SELF
Səviyyə , Dərs
Mövcuddur

1. Giriş

Gəlin təsəvvür edək ki, threadlər dondurma üçün növbədə dayanan insanlardır. Kimsə sakitcə dayanır, kiməsə isə tələsikdir ("Mənim qatar tez gəlir, keçirəsiz!"), və satıcı hamını eyni şəkildə dinləyir kimi görünə bilər, amma bəzən kimsəni növbədən qabaq servis edir — məsələn, uşaq ağlayan ananı. Elə thread prioritetləri də təxminən belədir.

C#-də (daha dəqiq .NET-də) hər bir thread-in öz prioriteti var — bu əməliyyat sisteminə həmin thread-in digər thread-lərlə müqayisədə nə dərəcədə "vacib" olduğunu bildirən ipucu kimidir. Bu əməliyyat sistemi üçün ciddi qayda deyil (heç kim zəmanət vermir ki, ən yüksək prioritetli thread həmişə bütün diqqəti alacaq), amma adətən yüksək prioritetli threadlərə daha çox CPU vaxtı ayrılır.

Bu nə vaxt faydalıdır?

  • İstifadəçi interfeyslərində: məsələn, ekran yenilənməsini uzun müddətli hesablamalarla yavaşlatmamaq üçün.
  • Oyunlarda: kadrların render edilməsi fonda xəritə generasiya edilməsindən daha önəmlidir.
  • Cavab vaxtı kritik olan tapşırıqlarda: avadanlıq idarəsi, siqnal emalı və s.

2. Thread prioritetləri: necə işləyir

C#-də thread prioriteti ilə işləmək sadədir — Thread obyektinin Priority xassəsi var. O, ThreadPriority enumerasiyasından qiymət alır:

Qiymət Təsvir
Lowest
Ən aşağı prioritet
BelowNormal
Orta səviyyədən aşağı
Normal
Normal (default)
AboveNormal
Orta səviyyədən yuxarı
Highest
Ən yüksək prioritet

Kod nümunəsi:

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        Thread lowPriorityThread = new Thread(PrintLowPriority);
        Thread highPriorityThread = new Thread(PrintHighPriority);

        lowPriorityThread.Priority = ThreadPriority.Lowest;
        highPriorityThread.Priority = ThreadPriority.Highest;

        lowPriorityThread.Start();
        highPriorityThread.Start();
    }

    static void PrintLowPriority()
    {
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine("Aşağı prioritet: " + i);
            Thread.Sleep(10); // Fərqi görmək üçün fasilə əlavə edək
        }
    }

    static void PrintHighPriority()
    {
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine("Yüksək prioritet: " + i);
            Thread.Sleep(10);
        }
    }
}

Qeyd

Praktikada, xüsusən müasir çoxnüvəli sistemlərdə və idarə olunan .NET mühitində prioritet sadəcə əməliyyat sisteminə tövsiyədir. OS (və .NET) yüksək prioritetli thread-ə daha çox vaxt ayırmağa çalışır, amma sərt zəmanətlər yoxdur. Məsələn, əgər sizin thread bütün CPU resursunu Highest prioritetində götürsə, interfeys donmağa başlaya və digər thread-lər əziyyət çəkə bilər.

3. Prioritetlərin dəyişdirilməsi

Threadlər və prioritetlər

graph LR
    A[Thread 1 - Lowest] -->|Az CPU vaxtı| OS(Əməliyyat sistemi)
    B[Thread 2 - Normal] --> OS
    C[Thread 3 - Highest] -->|Daha çox CPU vaxtı| OS
    OS --> CPU(Processor)

Niyə prioriteti dəyişdirmək lazımdır?

Hər şeyi Highest qoymaq həmişə ağlabatan deyil! Təsəvvür edin, bütün mağaza müştəriləri eyni anda "Məni əvvəlcə xidmət edin!" deməyə başlayar.

Prioriteti yalnız əsaslı səbəb olduqda dəyişin:

  • Log yazan fon thread — BelowNormal və ya Lowest edə bilərsiniz.
  • İstifadəçi girişini emal edən thread — AboveNormal.
  • CPU-intensiv, vaxt baxımından kritik olmayan işlər — aşağı prioritet.

Praktik məsləhət: Əgər tətbiq yavaşlayırsa, yoxlayın görək "tələbkar" yüksək prioritetli threadlər varmı.

4. .NET-də thread kateqoriyaları

C#-də ənənəvi olaraq iki növ thread ayırırlar: foregroundbackground. Maraqlıdır ki, "background" sözündən nəzərdə tutulan iş həmişə "fon" işi deyil. İndi izah edək.

Foreground threadlər (əsas)

  • Default olaraq sizin yaratdığınız threadlərin əksəriyyəti foreground olur.
  • Prosesdə ən azı bir foreground thread yaşadığı müddətcə tətbiq bitməyəcək, hətta digər hər şey "ölü" olsa belə.
  • Məsələn: proqramın əsas thread-i (Main), həmçinin new Thread() ilə yaradılan threadlər əgər dəyişdirilməyibsə.

Background threadlər (köməkçi)

  • Əgər bütün foreground threadlər bitibsə və yalnız background threadlər qalıbsa — proses sadəcə bitir və background threadlər xəbərdarlıq olmadan dayandırılır.
  • Onlar köməkçi işlər üçün istifadə olunur: loglama, fon metric göndərmə və s.
  • Thread-i background etmək üçün IsBackground xassəsini true qoyun:
Thread t = new Thread(SomeMethod);
t.IsBackground = true;
t.Start();

Fərqi göstərən nümunə

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        Thread backgroundThread = new Thread(() =>
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("Background thread işləyir... " + i);
                Thread.Sleep(500);
            }
            Console.WriteLine("Background thread SONLANDI.");
        });

        backgroundThread.IsBackground = true; // Thread-i background edirik!

        backgroundThread.Start();

        Console.WriteLine("Main 1 saniyə sonra işi bitirəcək.");
        Thread.Sleep(1000); // Bir saniyə gözləyirik
        Console.WriteLine("Main bitdi. Background thread ilə nə olacaq?");
    }
}

Nə görəcəksiniz?
Main bitə bilər və background thread yarımçıq dayandırılacaq. Bu, tətbiqin bağlanmasına mane olmamalı olan işlər üçün faydalıdır.

5. Thread növləri

ThreadPool (Thread hovuzu)

  • ThreadPool — çox sayda thread yaratmamaq üçün thread hovuzunu idarə edən mexanizmdir.
  • Qısa müddətli çoxsaylı işlər üçün istifadə olunur: paralel sorğu emalı, asinxron əməliyyatlar.
  • Hovuzdan götürülən threadlər həmişə background olar — onlar tətbiqin bağlanmasına mane olmur.

Nümunə: Thread hovuzunda kod işlətmək

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        ThreadPool.QueueUserWorkItem(DoWorkInThreadPool, "fon işi");
        Console.WriteLine("Main işi bitirir.");
        Thread.Sleep(500);
    }

    static void DoWorkInThreadPool(object? state)
    {
        Console.WriteLine("Hovuz threadi: " + state);
        Thread.Sleep(1000); // Yatmağa çalışaq
        Console.WriteLine("Hovuz threadi sona çatdı!");
    }
}

Nəzərə alın:
Əgər Main əvvəl bitərsə, hovuz threadi kəsilə bilər. Tamamlanmaya zəmanət lazımdırsa — foreground threadlərdən istifadə edin və ya açıq şəkildə tamamlanmanı gözləyin.

Multithreading-in inkişafı: Task, async/await

Müasir tətbiqlərdə əksər hallarda əl ilə thread yaratmaq (Thread) az istifadə olunur. Adətən Task və asinxron metodlardan istifadə edilir. Vacib məqamlar:

  • Hovuz threadləri və Task-lər background threadlərində işləyir.
  • Çox hallarda prioriteti dəyişmək lazım deyil — sağlam məntiqə və best practice-lərə əməl edin.

6. Faydalı nüanslar

Thread xassələri və davranış

Xassə Foreground Thread Background Thread ThreadPool Thread
IsBackground
false default olaraq true true
Tətbiqin bitməsi Tətbiq foreground threadlərdən ən azı biri yaşadığı müddətcə bitmir Tətbiq bütün foreground threadlər bitəndən sonra tamamlanır Tətbiq Main bitən kimi tamamlanır
İdarəetmə Tam nəzarət Tam nəzarət Birbaşa nəzarət yoxdur
Harada istifadə olunur Uzunmüddətli, vacib işlər (məsələn, DB server) Əhəmiyyətsiz işlər, fon əməliyyatları, loglama Qısa müddətli işlər, Task, asinxron əməliyyatlar
Prioritet Təyin etmək mümkündür Təyin etmək mümkündür Dəyişdirmək tövsiyə olunmur

Maraqlı məqamlar və xəbərdarlıqlar

  • Prioritet yalnız adi threadlər (Thread) üçün dəyişdirilə bilər, hovuzdan gələn işlər (Task, ThreadPool) üçün yox.
  • Hovuz threadləri həmişə Normal prioritetinə malikdir (onu dəyişmək olmaz).
  • Taskasync/await daha müasir yanaşmadır və prioritetlər və fon icra məsələlərini "kulislərin arxasında" gizlədir.

7. Prioritetlər və thread növləri ilə bağlı tipik səhvlər

Səhv №1: prioritetləri sui-istifadə etmək.
Bütün threadlərə səbəbsizcə Highest və ya hamısına Lowest təyin etmək fayda gətirməz. Bu işlərin icra balansını poza və tətbiqin cavabvericiliyini azalda bilər.

Səhv №2: background threadlərin gözlənilmədən dayandırılması.
Əgər vacib iş (məsələn, məlumatların saxlanması) background threaddə gedirsə və siz onun tamamlanmasını gözləmirsinizsə, məlumatların itməsi riski var. Background threadlər proses bitəndə avtomatik dayandırılır.

Səhv №3: prioritetdən yüksək nəticələr gözləmək.
Thread prioriteti (Priority) əməliyyat sisteminə tövsiyədir, amma thread-in ilk icra olunacağına zəmanət deyil.

2
Tapşırıq
C# SELF, səviyyə, dərs
Bağlanıb
Thread prioritetinin qurulması və yoxlanılması
Thread prioritetinin qurulması və yoxlanılması
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION