بتـــــاريخ : 2/26/2011 12:13:46 AM
الفــــــــئة
  • الحـــــــــــاسب
  • التعليقات المشاهدات التقييمات
    0 1364 0


    عالج برنامجك وأجعله أكثر قوة ! اول مقال باللغة العربية عن المعالجة بمكتبة Qt

    الناقل : elmasry | العمر :42 | الكاتب الأصلى : مصفوفة | المصدر : www.arabteam2000-forum.com

    كلمات مفتاحية  :
    عالج برنامج مكتبة Qt

    بسم الله الرحمن الرحيم
    اعزائي اعضاء المنتدى لا تذهبوا بعيدا في الكتب لأول مرة يتناول امر المعالجة في مقال عربي وهذه تحسب نقطة لي ادرجت فيه جميع ما يهمك في المعالجة والتزامن بالطبع المقال ليس كل شيئ ولكنه بوابة لكل شيئ اترككم مع المقال

    المعالجة
    تخيل لو ان برنامجك توقف بسبب رسالة او بسبب تحميل ملفات او لأي سبب اخرى فإن النقاط التي توقف فيها البرنامج لا يمكن ان يتجاوزها وتخيل هناك مهام لا يجب ان تتوقف بل يجب ان تعمل بمجرد عمل التطبيق وقد تلاحظ ذلك عند بداية تشغيل البرنامج وتحميله لأول مرة عموما دعنا نعرف مالحل ان المعالجات الحديثة تمكن لك اجراء اكثر من تطبيق في نفس الوقت فالمعالج ينقسم ولا يبالي بما يحدث في الآخر اظنك لقد تنبأت بالحل ….. نعم الحل هو ان تقسم عمل البرنامج في اقسام المعالج وهذا ما سوف نتعرف عليه في هذا الفصل عبر QThread. وهناك نوعين منه وهو الرئيسي والثانوي والرئيسي هو الذي يتحكم بعمل البرنامج بأسره وعند إقفاله يتم اقفال جميع المعالجات الثانوية اما الثانوي فإنه يعمل عمله الطبيعي متجاهلا ماحوله من معالجات ثانوية . ونتعرف ايضا على كيف نجعل المعالجات متزامنة بإستخدام QMutex عموما دعنا لا نستبق الحدث ونتدرج في الموضوع .

    QThread تحدثنا عنه في مقدمة الموضوع ولكن دعنا نتعرف اهم مافي هذا الصف من دوال: Start ويقوم بتشغيل المعالج وسوف يتم تنفيذ الكود داخل الدالة run. Wait وينتظر البرنامج حتى ينتهي من عمله او يمكن توقيته بحيث اذا انتهى الوقت يتم اغلق المعالج وبه بعض العمل وإن انتهى قبل نهاية التوقيت يتم اغلاق البرنامج مباشرة وبدون اعمال لم تنفذ. Sleep يقوم بإعطاء غفوة للبرنامج ومثله msleep Exit يتم الإنتها من تكرار البرنامج ويعيد قيمتين اما صفر او غيرها والصفر يعني عملية خروج صحيحة . Terminate ويطلق عليه عملية الإقفال العنيف حيث انه لا يدع للمعالج أي فرصة في العمل ويتم اغلاقه بعنف. وهناك اشارات يتم قذفها مثل finished وتقذف عن الإنتهاء من البرنامج بطريقة سليمة او started عند ابتداء المعالج بالعمل او terminated عند اقفال المعالج ولم يكمل عمله . عموم دعنا نأخذ مثال بسيط ونشرح عمله لتستوعب فكرتها .


    class TextThread : public QThread

             

            {

             

            public:

             

            TextThread( const QString &text );

           

            void run();

             

            private:

             

            QString m_text;

             

            };



    هذا الكلاسس يحوي التالي دالة البناء ودالة عمل المعالج ومتغير نصي يحفظ ماقمت بكتابته داخل متغير دالة البناء.
     
    bool stopThreads =false;

    قمنا بإنشاء هذا المتغير لينبهنا في طلب توقف المعالج سوف تعرف لماذا وضعناه في القادم
    .
     
    TextThread::TextThread(constQString&text ):QThread(){m_text = text;}


    دالة البناء وتقوم بتهيئة المتغير
    m_text .
     
    voidTextThread::run(){

             

           
    while(!stopThreads ){

             

            qDebug
    ()<< m_text;

             

            sleep
    (1);}

             

           
    }


    وهذه دالة عمل المعالج وسوف تبدأ بالشغل عند استدعاء الأمر start في الدالة main
    عمومما دعنا نتفحص ما بداخلها لقد قمن بتكرار الحدث لكي لا يتوقف الا اذا طلبنا ايقاف البرنامج وذلك عن طريق تحويل المتغير
    stopThreads الى true ثم
    نقوم بطباعة المحارف التي ارسلناها عبر دالة البناء وفي النهاية قمنا
    بإعطاء غفوة للمعالج اذا ما انتهت يقوم بتكرير الحدث مرة أخرى .
    الآن سوف نتعرف على الدالةmain


                                                      

            int main( int argc, char **argv )

             

            {

             

            QApplication app( argc, argv );

             

            TextThread mohammed( "mohammed" ), alabdaly( "alabdaly" );

             

            mohammed.start();

             

            alabdaly.start();

             

            QMessageBox::information( 0, "Threading", "Close me to stop!" );

             

            stopThreads = true;

             

            foo.wait();

             

            bar.wait();

             

            return 0;

             

            }


    قمنا بداية الأمر بإنشاء معالجين من التي صنعناها الأول بإسم mohammed والآخر بإسم alabdaly ثم طلبنا بتشغيل المعالجات بإستخدام الأمر start ثم امرنا بضهور رسالة من المعلوم لك مسبقا عند ظهور أي رسالة يتم ايقاف عمل المعالج حتى تغلق النافذة ولكن المعالجات mohammed & alabdaly مازالا مستمرين في العمل !!!!! عموما هذا هو مانقصده في شرحنا كله بعد إغلاق الرسالة يتم ارسال طلب اقفال البرنامج بتحويل المتغير stopThreads الى true قد تكون بعض العمليات لم تعالج لذ سوف يصبر البرنامج حتى يتم معالجة جميع الأوامر ومن ثم يتم اقفال البرنامج بإرجاع القيمة 0 . في الرنامج السابق كان الناتج : "mohammed" "alabdaly" "alabdaly" "mohammed" "alabdaly" "mohammed" "alabdaly" …………. ………….
    الى ان تقوم بإيقاف البرنامج لاحظ انه عملية التحرير تقوم بشكل عشوائي هذا دليل ان المعالجات لا تتأثر بعضها البعض ولكن ماذا لو اردت ان تحدث تناسق بينهم وتجعل عملهم يقوم بشكل متزامن الأول تلو الآخر هذا ما سوف تتعرف عليه فيQMutex .


    ---------------------------------------------------


    التزامن
    اذا اردت ان تعمل المعالجات بشكل منتظم ومتناسق مع بعضها البعضها البعض فعليك ان تتعامل مع QMutex
    انه صف يقوم بإغلاق على كود او فتحه بحيث لا يسمح معالجة بداخله او يسمح كل ماتحته يعتبر بداخله
    لذلك عند مرور المعالجة بmutex مغلق فإنه يتوقف حتى يتم فتحه(اشارة مرور)
    ماذا نستفيد ؟؟؟
    لن اجيب على هذا السؤال الى بعد دراسة الكود التالي
    قم بوضع متغير عام في نفس الكود السابق
    QMutex mutex;

    نفس الكود السابقة استبدل محتوى الدالة run بهذا المحتوى
    void TextThread::run()

           

              {

           

                      while ( !stopThreads )

           

                      {

           

                              mutex.lock();

           

                              if ( stopThreads )

           

                              {

           

                                      mutex.unlock();

           

                                      return;

           

                              }

           

                              qDebug() << m_text;

           

                              sleep( 1 );

           

                              mutex.unlock();

           

                      }

           

              }






     
     
    لقد قمنا بإنشاء متغيرعام mutex سوف يتعامل معه المتغيرين mohammed & alabdaly ونفترض ان mohammed سبق alabdaly وهو في الغالب فإن التالي هو ماسوف يحدث
    سوف يقوم mohammed بإقفال الmutex وعندما يأتي بعده المتغير alabdaly سيجد mutex مغلق وينتظر ان يفتحه mohammed في هذه الأثناء سوف يقوم بالتأكد من انا معالجة البرنامج مستمرة وإلا قام بفتح القفل عموما سوف عموما لو اننا ابقيان على المعالج يعمل فإنه يقوم بتحرير النصmohammed وهو المرسل في الدالة main عن طريق دالة البناء ل mohammed ثم يإخذ غفوة وبعدها يفتح mutex
    ما إن يريد ان يبدأ بدورته التالية يكون alabdaly قد سبقه الى مابداخل ال mutex وقام بإقفاله وبهذا سوف ينتظر mohammed بفتح القفل (إشارة مرور) وهكذا تستمر الدورة الى ان يتم طلب ابقاف المعالج عبر المتغير stopThreadsوذلك بإعطائه القيمة true .
    سوف تجد الناتج من هذه العملية منظما وبطريقة افضل من سابقه
    "mohammed"
    "alabdaly"
    "mohammed"
    "alabdaly"
    "mohammed"
    "alabdaly"
    "mohammed"
    "alabdaly"
    "mohammed"
    "alabdaly"
    ……….
    …….....
    وهناك صفوف أخرى تقوم بمعالجة mutex مثل QMutexLockerوهي تتلقا مؤشر ل QMutex وعند ادخالها في دالة تقوم بالإغلاق عليه وعند تدميرها يتم فتح ال mutex بشكل تلقائي[font="DejaVu Sans serif"].




    اخواني هناك مواضيع اخرى في المعالجة مثل معالجة التكرارات ومعالجة الدخول الى المتغيرات ومعالجة القراءة والكتابة سوف اسردها في نفس الموضوع في وقت لاحق

    ولكن اضمن لك ام فهمت هذا المقال فإنك فهمت 80% من المعالجة



    اخوكم محمد العبدلي رئيس فريق مصفوفة و مشرف في موقع qt-ar

    كلمات مفتاحية  :
    عالج برنامج مكتبة Qt

    تعليقات الزوار ()