اذهب إلى المحتوى

السؤال

Recommended Posts

  • 1
نشر

في البرمجة المتوازية (التفرعية) parallel programming يقوم بالمبرمج بإنشاء عدة مسالك thread لكي يضمن عمل البرنامج بشكل أفضل مستغلا بنية المعالجات التي تحوي عدة مسالك، في نفس الوقت ربما هنالك أحد هذه المسالك يعتمد على نتيجة مسلك آخر أي عليه أن ينتظر إنتهاء تنفيذه ليتابع التنفيذ عمله، أو تحديد نقطة في الشيفرة لتجميع نتائجعدة مسالك مختلفة ومن ثم تجميع هذه النتائج بالطريقة المناسبة.

تدعم #C عدة أنواع من الدالة join:

  • أحدها بدون وسطاء ويقوم بعملية انتظار لتمام انتهاء المسلك من عمله
  • والثاني يأخذ وسيط رقم صحيح مقدراً بواحدة ميلي ثانية حيث ينتظر إما لانتهاء (يتصرف كمهلة انتظار) هذه المدة أو انتهاء المسلك بالشكل العادي
    // انتظار لمدة ثانية    millisecondsTimeout
    thread.Join(1000);

     

مثال عام:

// إنشاء مسلكين 
Thread thr1 = new Thread(new ThreadStart(obj.mythread)); 
Thread thr2 = new Thread(new ThreadStart(obj.mythread1)); 

// تشغيل المسلك الأول
thr1.Start(); 

// انتظار انتهاء المسلك الأول
thr1.Join(); 
// تشغيل المسلك الثاني
thr2.Start();

 

  • 1
نشر

تقوم بإيقاف جميع التعليمات التي تأتي بعدها ضمن الكود حتى يتم تنفيذ ال thread الذي يقوم بالاستدعاء، لفهم ذلك :
في البداية و كما نعلم أن ال thread هو طريق إلى وحدة المعالج، ففي حال لدينا كود ما كبير  وكان هنالك إمكانية للتفريع، و قمنا بإنشاء عدد من ال Threads، فإن كل thread  منها يصل إلى نواة من أموية المعالج، وبالتالي كل نواة تنفذ جزء من الكود، و بالتالي تنفيذ الكود يكون بشكل متساير ( متوازي) مما يؤدي لتسريع تنفيذ الكود.
إذن مجال التنفيذ سيكون متداخل، فلو أخذنا المثال البسيط التالي (سنقتصر على ذكر الأفكار اللازمة لفهم الطريقة  join() فقط) :
( الصف Helper يحوي الطريقتين printA  تقوم  بطباعة A  مئة مرة، printB  تقوم بطباعة B  مئة مرة).

Class Helper {
     Public void PrintA(){ 
         for  ( int i=0 ; i<100 ; i++ )  {
                         console.WriteLine("A");
          }
  }
          Public void PrintB(){ 
         for  ( int i=0 ; i<100 ; i++ )  {
                         console.WriteLine("B");
          }
  }
    
}

( في ال main class أخذنا غرض من الصف Helper واستدعينا طرائقه ، ثم أنشئنا لكل طريقة thread  خاص ، لا ننسى أن ال التابع main() عبارة عن thread  أساسي يتم تنفيذه).

Class program {
     Public static void main() {
     Helper h = new Helper ();
     Thread th1 = new Thread (h.printA());
     Thread th2 = new Thread (h.printB());
     Th1.start();
     Th2.start ();
      for ( int i =0 ; i < 100; i++ ) {
                     console.WriteLine ( "C" );
      }
   }
}

الآن أصبح لدينا ثلاثة نياسب (th1 يطبع A مئة مرة، th2يطبع B مئة مرة، thread mainيطبع C مئة مرة).
التنفيذ متداخل و يكون الخرج هنا  بعد التنفيذ: (  طباعة A  مئة مرة و B مئة مرة  و C مئة مرة ) بشكل متداخل.
الآن الجزء المهم لمعرفة  وظيفة الطريقة join(): ماذا نفعل اذا أردنا أن نطبع A مئة  ثم طباعة B  مئة مرة   ثم طباعة C مئة مرة ؟
الجواب نستخدم التعليمة join() بالشكل :

th1.start();
th1.join();
th2.start();
th2.join();
for(int i=0;i<100;++i){
         onsole.WriteLine("C");
}

سؤال بطريقة أخرى لفهم join() ، ماهو الخرج في حال كانت التعليمات بالشكل :

th1.start();
th2.start();
th1.join();
th2.join();
for(int i=0;i<100;++i){
         onsole.WriteLine("C");
}

الخرج : طباعة C مئة مرة بعد طباعة كل من A,B بشكل متداخل ، بشكل مفصل:
التعليمة th1.join()  تقوم بإيقاف ال main(طباعة C)حتى يتم طباعة A مئة مرة.
(إلى هنا يكون المتوقع حتى الآن طباعة A و  B  بشكل متداخل وعندما تتم طباعة A مئة مرة يبدأ تنفيذ النيسب main  بالتالي بدئ طباعة C بشكل متداخل مع B  إن لم تكن منتهية )
 لكن لدينا التعليمة التالية وهي  th2.join()تقوم بإيقاف ال main(طباعة C)حتى يتم طباعة B مئة مرة .. بالتالي أصبح الخرج المتوقع (طباعة Aمئة مرة و B مئة مرة ) بشكل متداخل ومن ثم طباعة C  مئة مرة .

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...