C # - Multithreading

SEBUAH threaddidefinisikan sebagai jalur eksekusi suatu program. Setiap utas menentukan aliran kontrol yang unik. Jika aplikasi Anda melibatkan operasi yang rumit dan memakan waktu, sebaiknya setel jalur atau thread eksekusi yang berbeda, dengan setiap thread menjalankan tugas tertentu.

Utas adalah lightweight processes. Salah satu contoh umum penggunaan thread adalah implementasi pemrograman konkuren oleh sistem operasi modern. Penggunaan utas menghemat pemborosan siklus CPU dan meningkatkan efisiensi aplikasi.

Sejauh ini kami menulis program di mana satu utas berjalan sebagai proses tunggal yang merupakan contoh aplikasi yang sedang berjalan. Namun, dengan cara ini aplikasi dapat melakukan satu pekerjaan dalam satu waktu. Untuk membuatnya menjalankan lebih dari satu tugas sekaligus, itu dapat dibagi menjadi utas yang lebih kecil.

Siklus Hidup Benang

Siklus hidup utas dimulai ketika objek kelas System.Threading.Thread dibuat dan berakhir ketika utas dihentikan atau menyelesaikan eksekusi.

Berikut adalah berbagai kondisi dalam siklus hidup utas -

  • The Unstarted State - Ini adalah situasi ketika instance utas dibuat tetapi metode Mulai tidak dipanggil.

  • The Ready State - Ini adalah situasi ketika utas siap untuk dijalankan dan menunggu siklus CPU.

  • The Not Runnable State - Sebuah utas tidak dapat dieksekusi, kapan

    • Metode tidur telah dipanggil
    • Metode menunggu telah dipanggil
    • Diblokir oleh operasi I / O
  • The Dead State - Ini adalah situasi ketika utas menyelesaikan eksekusi atau dibatalkan.

Benang Utama

Di C #, itu System.Threading.Threadkelas digunakan untuk bekerja dengan utas. Ini memungkinkan membuat dan mengakses utas individu dalam aplikasi multithread. Utas pertama yang dijalankan dalam suatu proses disebutmain benang.

Ketika program C # mulai dijalankan, utas utama secara otomatis dibuat. Utas dibuat menggunakanThreadkelas disebut anak utas utas utama. Anda dapat mengakses utas menggunakanCurrentThread milik kelas Thread.

Program berikut menunjukkan eksekusi utas utama -

using System;
using System.Threading;

namespace MultithreadingApplication {
   class MainThreadProgram {
      static void Main(string[] args) {
         Thread th = Thread.CurrentThread;
         th.Name = "MainThread";
         
         Console.WriteLine("This is {0}", th.Name);
         Console.ReadKey();
      }
   }
}

Ketika kode di atas dikompilasi dan dijalankan, itu menghasilkan hasil sebagai berikut -

This is MainThread

Properti dan Metode Kelas Thread

Tabel berikut menunjukkan beberapa yang paling umum digunakan properties dari Thread kelas -

Sr.No. Deskripsi properti
1

CurrentContext

Mendapatkan konteks saat ini di mana thread sedang dieksekusi.

2

CurrentCulture

Mendapat atau menetapkan budaya utas saat ini.

3

CurrentPrinciple

Mendapat atau menyetel pokok utas saat ini (untuk keamanan berbasis peran).

4

CurrentThread

Mendapatkan utas yang sedang berjalan.

5

CurrentUICulture

Mendapat atau menyetel budaya saat ini yang digunakan oleh Manajer Sumber Daya untuk mencari sumber daya khusus budaya pada waktu proses.

6

ExecutionContext

Mendapat objek ExecutionContext yang berisi informasi tentang berbagai konteks utas saat ini.

7

IsAlive

Mendapat nilai yang menunjukkan status eksekusi utas saat ini.

8

IsBackground

Mendapat atau menetapkan nilai yang menunjukkan apakah suatu utas adalah utas latar belakang atau tidak.

9

IsThreadPoolThread

Mendapat nilai yang menunjukkan apakah suatu utas termasuk dalam kumpulan utas terkelola atau tidak.

10

ManagedThreadId

Mendapatkan pengenal unik untuk untaian terkelola saat ini.

11

Name

Mendapat atau menetapkan nama utas.

12

Priority

Mendapat atau menetapkan nilai yang menunjukkan prioritas penjadwalan utas.

13

ThreadState

Mendapat nilai yang berisi status utas saat ini.

Tabel berikut menunjukkan beberapa yang paling umum digunakan methods dari Thread kelas -

Sr.No. Metode & Deskripsi
1

public void Abort()

Menaikkan ThreadAbortException di utas tempat ia dipanggil, untuk memulai proses mengakhiri utas. Memanggil metode ini biasanya menghentikan utas.

2

public static LocalDataStoreSlot AllocateDataSlot()

Mengalokasikan slot data tanpa nama di semua utas. Untuk kinerja yang lebih baik, gunakan bidang yang ditandai dengan atribut ThreadStaticAttribute sebagai gantinya.

3

public static LocalDataStoreSlot AllocateNamedDataSlot(string name)

Mengalokasikan slot data bernama di semua utas. Untuk kinerja yang lebih baik, gunakan bidang yang ditandai dengan atribut ThreadStaticAttribute sebagai gantinya.

4

public static void BeginCriticalRegion()

Memberi tahu host bahwa eksekusi akan memasuki wilayah kode yang efek utasnya dibatalkan atau pengecualian yang tidak tertangani dapat membahayakan tugas lain dalam domain aplikasi.

5

public static void BeginThreadAffinity()

Memberi tahu host bahwa kode yang dikelola akan menjalankan instruksi yang bergantung pada identitas utas sistem operasi fisik saat ini.

6

public static void EndCriticalRegion()

Memberi tahu host bahwa eksekusi akan memasuki wilayah kode di mana efek thread yang dibatalkan atau pengecualian yang tidak tertangani terbatas pada tugas saat ini.

7

public static void EndThreadAffinity()

Memberi tahu host bahwa kode yang dikelola telah selesai menjalankan instruksi yang bergantung pada identitas utas sistem operasi fisik saat ini.

8

public static void FreeNamedDataSlot(string name)

Menghilangkan keterkaitan antara nama dan slot, untuk semua utas dalam proses. Untuk kinerja yang lebih baik, gunakan bidang yang ditandai dengan atribut ThreadStaticAttribute sebagai gantinya.

9

public static Object GetData(LocalDataStoreSlot slot)

Mengambil nilai dari slot yang ditentukan pada thread saat ini, dalam domain thread saat ini. Untuk kinerja yang lebih baik, gunakan bidang yang ditandai dengan atribut ThreadStaticAttribute sebagai gantinya.

10

public static AppDomain GetDomain()

Mengembalikan domain saat ini di mana utas saat ini berjalan.

11

public static AppDomain GetDomainID()

Mengembalikan pengenal domain aplikasi unik

12

public static LocalDataStoreSlot GetNamedDataSlot(string name)

Mencari slot data bernama. Untuk kinerja yang lebih baik, gunakan bidang yang ditandai dengan atribut ThreadStaticAttribute sebagai gantinya.

13

public void Interrupt()

Menyela utas yang ada dalam status utas WaitSleepJoin.

14

public void Join()

Memblokir utas panggilan hingga utas berakhir, sambil terus melakukan pemompaan COM dan SendMessage standar. Metode ini memiliki bentuk kelebihan muatan yang berbeda.

15

public static void MemoryBarrier()

Sinkronisasi akses memori sebagai berikut: Prosesor yang menjalankan utas saat ini tidak dapat menyusun ulang instruksi sedemikian rupa sehingga memori yang diakses sebelum panggilan ke MemoryBarrier dijalankan setelah akses memori yang mengikuti panggilan ke MemoryBarrier.

16

public static void ResetAbort()

Membatalkan Pembatalan yang diminta untuk utas saat ini.

17

public static void SetData(LocalDataStoreSlot slot, Object data)

Menyetel data di slot yang ditentukan pada thread yang sedang berjalan, untuk domain thread tersebut saat ini. Untuk kinerja yang lebih baik, gunakan bidang yang ditandai dengan atribut ThreadStaticAttribute.

18

public void Start()

Memulai utas.

19

public static void Sleep(int millisecondsTimeout)

Menjeda utas selama jangka waktu tertentu.

20

public static void SpinWait(int iterations)

Menyebabkan utas menunggu berapa kali ditentukan oleh parameter iterasi

21

public static byte VolatileRead(ref byte address)

public static double VolatileRead(ref double address)

public static int VolatileRead(ref int address)

public static Object VolatileRead(ref Object address)

Membaca nilai bidang. Nilai ini adalah yang terakhir ditulis oleh prosesor mana pun di komputer, terlepas dari jumlah prosesor atau status cache prosesor. Metode ini memiliki bentuk kelebihan muatan yang berbeda. Hanya beberapa yang diberikan di atas.

22

public static void VolatileWrite(ref byte address,byte value)

public static void VolatileWrite(ref double address, double value)

public static void VolatileWrite(ref int address, int value)

public static void VolatileWrite(ref Object address, Object value)

Menulis nilai ke bidang dengan segera, sehingga nilai dapat dilihat oleh semua prosesor di komputer. Metode ini memiliki bentuk kelebihan muatan yang berbeda. Hanya beberapa yang diberikan di atas.

23

public static bool Yield()

Menyebabkan thread pemanggil menghasilkan eksekusi ke thread lain yang siap dijalankan pada prosesor saat ini. Sistem operasi memilih utas yang akan digunakan.

Membuat Thread

Thread dibuat dengan memperluas kelas Thread. Kelas Thread yang diperluas kemudian memanggilStart() metode untuk memulai eksekusi utas anak.

Program berikut mendemonstrasikan konsep -

using System;
using System.Threading;

namespace MultithreadingApplication {
   class ThreadCreationProgram {
      public static void CallToChildThread() {
         Console.WriteLine("Child thread starts");
      }
      static void Main(string[] args) {
         ThreadStart childref = new ThreadStart(CallToChildThread);
         Console.WriteLine("In Main: Creating the Child thread");
         Thread childThread = new Thread(childref);
         childThread.Start();
         Console.ReadKey();
      }
   }
}

Ketika kode di atas dikompilasi dan dijalankan, itu menghasilkan hasil sebagai berikut -

In Main: Creating the Child thread
Child thread starts

Mengelola Thread

Kelas Thread menyediakan berbagai metode untuk mengelola thread.

Contoh berikut menunjukkan penggunaan file sleep() metode untuk membuat utas jeda untuk jangka waktu tertentu.

using System;
using System.Threading;

namespace MultithreadingApplication {
   class ThreadCreationProgram {
      public static void CallToChildThread() {
         Console.WriteLine("Child thread starts");
         
         // the thread is paused for 5000 milliseconds
         int sleepfor = 5000; 
         
         Console.WriteLine("Child Thread Paused for {0} seconds", sleepfor / 1000);
         Thread.Sleep(sleepfor);
         Console.WriteLine("Child thread resumes");
      }
      
      static void Main(string[] args) {
         ThreadStart childref = new ThreadStart(CallToChildThread);
         Console.WriteLine("In Main: Creating the Child thread");
         
         Thread childThread = new Thread(childref);
         childThread.Start();
         Console.ReadKey();
      }
   }
}

Ketika kode di atas dikompilasi dan dijalankan, itu menghasilkan hasil sebagai berikut -

In Main: Creating the Child thread
Child thread starts
Child Thread Paused for 5 seconds
Child thread resumes

Menghancurkan Thread

Itu Abort() metode digunakan untuk menghancurkan utas.

Runtime membatalkan utas dengan melempar ThreadAbortException. Pengecualian ini tidak dapat ditangkap, kontrol dikirim ke blok terakhir , jika ada.

Program berikut menggambarkan hal ini -

using System;
using System.Threading;

namespace MultithreadingApplication {
   class ThreadCreationProgram {
      public static void CallToChildThread() {
         try {
            Console.WriteLine("Child thread starts");
            
            // do some work, like counting to 10
            for (int counter = 0; counter <= 10; counter++) {
               Thread.Sleep(500);
               Console.WriteLine(counter);
            }
            
            Console.WriteLine("Child Thread Completed");
         } catch (ThreadAbortException e) {
            Console.WriteLine("Thread Abort Exception");
         } finally {
            Console.WriteLine("Couldn't catch the Thread Exception");
         }
      }
      static void Main(string[] args) {
         ThreadStart childref = new ThreadStart(CallToChildThread);
         Console.WriteLine("In Main: Creating the Child thread");
         
         Thread childThread = new Thread(childref);
         childThread.Start();
         
         //stop the main thread for some time
         Thread.Sleep(2000);
         
         //now abort the child
         Console.WriteLine("In Main: Aborting the Child thread");
         
         childThread.Abort();
         Console.ReadKey();
      }
   }
}

Ketika kode di atas dikompilasi dan dijalankan, itu menghasilkan hasil sebagai berikut -

In Main: Creating the Child thread
Child thread starts
0
1
2
In Main: Aborting the Child thread
Thread Abort Exception
Couldn't catch the Thread Exception