ایجاد نخ ها(رشته ها-بندها) با کمک کلاس Thread در سی شارپ

مقالات آموزشی

برنامه نویسی ناهمزمان و چندرشته ای یک ویژگی مهم برای اشتراک زمانی و پردازش موازی است. برنامه نویسی غیرهمزمان می تواند از چندرشته ای (multithreading) استفاده کند یا خیر. در این آموزش به تعریف پوسس ها، نخ ها و روش کار با نخ ها در زبان سی شارپ می پردازیمتعریف پروسس (Process)

برنامه های کامپیوتر صرفا اجرا پذیر هستند, باینری (یا طور دیگر ), این برنامه ها روی دیسک قرار دارند. اینها نمی توانند کاری انجام بدهند(به اصطلاح مرده هستند) تا زمانی که داخل حافظه بارگذاری شوند و از سیستم عامل درخواست کنند. پروسس یک برنامه در حال اجرا است.
هر پروسس یک ادرس فضا , حافظه و یک پشته داده دارد. سیستم عامل کنترل کننده تمام پروسس های در حال اجرا بر روی سیستم است, و زمان رو میان انها به طور خوب تقسیم می کند. پروسس ها می توانند چند شاخه بشوند یا یک پروسس جدید برای انجام دیگر کارها ایجاد کنند, هر یک از این پروسس های جدید حافظه و پشته داده و… خودشان را دارند.

تعریف نخ (Thread)

 Thread ها یا نخ ها به قطعه کدهایی گفته می شود که به صورت موازی و همزمان با هم اجرا می شوند و به شما این امکان را می دهند برنامه هایی را طراحی و پیاده سازی کنید که می توانند چندین کار را با هم انجام دهند به طور مثال :جستجوی چند فایل یا گرفتن اطلاعات از طریق شبکه و ذخیره انها در دیسک. البته اصولا نخ ها به صورت همزمان اجرا نمی شوند بلکه CPU براساس تنظیم زمان خود یک زمان غیر قابل درک برای انسان را در نظر می گیرد سپس در این مدت زمان یک کار را انجام داده و پس از اتمام این زمان به سراغ کار بعدی می رود به اصطلاح در کارهای خود سوییچ می کند. به این مدت زمان کوتاه اصطلاحا Time Slice یا پرش زمان می گویند.

چند نخی (multi threading)

 multi threading در واقع جدا سازی پردازش ها از یکدیگرست. مثلا در یک برنامه سی شارپ شما به صورت پیش فرض کل برنامه شما در یک نخ اجرا میشود. اگر در این برنامه یک حلقهFor دارید که ممکنست تا بی نهایت طول بکشد، تا زمانی که به اتمام نرسد هیچ کار دیگری نمیتوانید انجام دهید. اما اگه این حلقه را در یک نخ اجرا کنید و بقیه عملیات رادر نخ دیگری، هر دو این عملیات به طور همزمان اجرا میشوند و هیچکدام به دیگری تاثیری نمیگذارد. همچنین استفاده دیگری که multi threadingدارد این است که یک پردازش بزرگ رابه چند پردازش کوچیک بشکنیم و هرکدام رادریک نخ اجرا کنیم که باعث افزایش سرعت میشود. در ضمن هرکدام از نخ ها دچار مشکل شوند و هنگ کنند بقیه ترد ها به کار خود ادامه میدهند.

مزایای استفاده از Threadها

 ۱ـ به اشتراک‌گذاری منابع پردازشی سیستم بین Threadها.
۲ـ اجرای کارهای سنگین (مانند ارسال اطلاعات در شبکه، پردازش عکس و…) توسط Threadهای دیگر باعث می‌شود Threadاصلی که UI و برقراری ارتباط با کاربر را انجام می‌دهد، درگیر کارهای سنگین نشده و باعث هنگ کردن آن نمی‌شود.
۳ـ استفاده از Threadها یک اجرای انتزاعی هم روند را برای اجرای برنامه فراهم می‌کند.
۴ـ برنامه‌هایی که از چند Thread استفاده می‌کنند(Multi Threads Program) در سیستم‌هایی که چند پردازنده دارد سریع‌تر و راحت‌تر اجرا می‌شوند.

معایب استفاده از Thread ها

۱ـ کدنویسی شما به عنوان برنامه‌نویس، پیچیده می‌شود.
۲ـ نیاز به تشخیص/ اجتناب/‌ حل مشکلات deadlocks (در مورد deadlock در شماره‌های پیش توضیح داده‌ایم) وجود دارد.

۳ـ مدیریت بیشتر روی خطاهای مدیریت نشده (Unhandled Exception).

کار با Thread ها در c#

 در ابتدا باید یک Object از نوع System.Threading.Thread ایجاد کنید.
کلاس Thread تنها یک ایجادکننده (Constructor) دارد که یک ThreadStart (که یک Delegate است) می گیرد. برای توابع static می توان مستقیما نام تابع را ارسال کرد. تابع نوشته شده باید هیچ پارامتری نداشته باشد و هیچ مقداری را نیز برنگرداند (یعنی void باشد) به این علت که تابع اصلی این گونه تعریف شده است.
بعد از ایجاد Thread می توانید آن را با Start، شروع کنید:

using System;
using System.Threading;
namespace sample1
{
class Program
{
static void Main(string[] args)
{
Thread thread = new Thread(DoTask);
}
thread.Start();
}
static public void DoTask()
{
Console.WriteLine("thread created...");
}
}

برنامه زیر بعد از ایجاد نخ، ویژگی های آن را از جمله نام، اولویت (priority) و نوع آن (پیش زمینه یا پس زمینه) را تنظیم می کند.


using System;
using System.Threading;
namespace sample1
{
static void Main(string[] args)
class Program
{
{
Thread thread = new Thread(DoTask);
thread.Name = "My new thread";// Asigning name to the thread
thread.Priority = ThreadPriority.AboveNormal;// Setting thread priority
thread.IsBackground = false;// Made the thread forground
thread.Start();// Start DoTask method in a new thread
Console.WriteLine("thread created...");
//Do other task in main thread
}
static public void DoTask()
{
}
}

مثال زیر نمونه کامل تری از نخ ها را نشان می دهد. یک کلاس دارای دو تابع Thread1 و Thread2 تعریف شده و در برنامه اصلی با ایجاد دو نخ، برای هر کدام یکی از این دو تابع اجرا شده است.


using System;
using System.Threading;
public class MyThread {
public static void Thread1() {
for (int i = 0; i < 10; i++) {
}
Console.WriteLine("Thread1 {0}", i);
}
Console.WriteLine("Thread2 {0}", i);
public static void Thread2() {
for (int i = 0; i < 10; i++) {
}
Console.WriteLine("Before start thread");
}
}
public class MyClass {
public static void Main() {
Thread tid2 = new Thread(new ThreadStart(MyThread.Thread2 ) );
Thread tid1 = new Thread(new ThreadStart(MyThread.Thread1 ) );
tid1.Start();
tid2.Start();
}
}

خروجی این برنامه بصورت زیر است. یعنی هر دو تابع پشت سر هم اجرا شده اند:


Before start thread
Thread1 0
Thread1 1
Thread1 4
Thread1 2
Thread1 3
Thread1 5
Thread1 9
Thread1 6
Thread1 7
Thread1 8
Thread2 0
Thread2 5
Thread2 1
Thread2 2
Thread2 3
Thread2 4
Thread2 6
Thread2 9
Thread2 7
Thread2 8

به جای برنامه فوق می توان از برنامه زیر استفاده کرد:

using System;
using System.Threading;
public class MyThread {
public void Thread1() {
for (int i = 0; i < 10; i++) {
Console.WriteLine("Thread1 {0}", i);
}
}
public class MyClass {
public void Thread2() {
for (int i = 0; i < 10; i++) {
Console.WriteLine("Thread2 {0}", i);
}
public static void Main() {
Thread tid2 = new Thread(new ThreadStart(thr.Thread2) );
Console.WriteLine("Before start thread");
MyThread thr = new MyThread();
Thread tid1 = new Thread(new ThreadStart(thr.Thread1) );
tid1.Start();
tid2.Start();
}
}

در نمونه برنامه زیر کلاس myThread دارای یک تابع بنام Thread1 است و در برنامه اصلی دو نمونه از نوع این کلاس ایجاد شده و برای هر نخ، تابع یکی از این نمونه ها فراخوانی شده است:

using System;
using System.Threading;
public class MyThread {
public void Thread1() {
for (int i = 0; i < 10; i++) {
Console.WriteLine("Hello world {0}", i);
}
}
}
public class MyClass {
public static void Main() {
MyThread thr2 = new MyThread();
Console.WriteLine("Before start thread");
MyThread thr1 = new MyThread();
tid1.Start();
Thread tid1 = new Thread(new ThreadStart(thr1.Thread1) );
Thread tid2 = new Thread(new ThreadStart(thr2.Thread1) );
tid2.Start();
}
}

در برنامه زیر تابع نوشته شده برای نخ بعد از چاپ یک خروجی به مدت یک میلی ثانیه توقف می کند ، در این فاصله پردازنده به نخ دیگر داده شده و یک خروجی برای او چاپ می کند. به عبارتی پردازنده دائماً بین نخ ها دست به دست می شود.

using System;
using System.Threading;
public class MyThread {
public void Thread1() {
for (int i = 0; i < 10; i++) {
Console.WriteLine("Hello world " + i);
Thread.Sleep(1);
}
}
}
public class MyClass {
MyThread thr1 = new MyThread();
public static void Main() {
Console.WriteLine("Before start thread");
Thread tid2 = new Thread(new ThreadStart(thr2.Thread1) );
MyThread thr2 = new MyThread();
Thread tid1 = new Thread(new ThreadStart(thr1.Thread1) );
tid1.Start();
tid2.Start();
}
}

خروجی حاصل از این برنامه بصورت زیر است:

Before start thread
Hello world 0
Hello world 1
Hello world 0
Hello world 1
Hello world 3
Hello world 2
Hello world 2
Hello world 3
Hello world 5
Hello world 4
Hello world 4
Hello world 5
Hello world 6
Hello world 8
Hello world 6
Hello world 7
Hello world 7
Hello world 8
Hello world 9
Hello world 9

برچسب ها

محصولات پیشنهادی


نظرات کاربران


نظرات برای مقالات فناوری و آموزشی | بدون نظر »

کاربر عزیز، لطفاً دیدگاه ارزشمند خود را از طریق فرم زیر برای ما ارسال کنید:

درباره کدنویسان
آکادمی کدنویسان جهت کمک به دانشجویان رشته های کامپیوتر و فناوری اطلاعات و همه علاقمندان به طراحی و برنامه نویسی برای ویندوز، وب و موبایل ایجاد شده است.
بیشتر آموزش های سایت کدنویسان، بصورت رایگان ارائه شده است و بعضی بسته های آموزشی تصویری و نیز نرم افزارهای پیاده سازی شده در ازای پرداخت، قابل دانلود هستند.
هر گونه نظر، انتقاد یا پیشنهادی در مورد مطالب یا عملکرد کدنویسان دارید، حتما با ما در میان بگذارید.
نمادهای اعتماد ما


تماس با ما
  • شماره همراه : ۰۹۱۵۱۶۰۴۰۶۸
  • آی دی تلگرام : @mmoha94
  • پست الکترونیکی : mohammadi.sm@gmail.com
  • آدرس پستی : بیرجند، خیابان پیروزی، پیروزی ۹، پلاک ۲۸
کلیه حقوق متعلق به سایت کدنویسان است، انتشار و کپی برداری از مطالب این سایت غیرمجاز بوده و پیگرد قانونی دارد.