• 0
مصفوفة

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

سؤال

بسم الله الرحمن الرحيم

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

المعالجة

تخيل لو ان برنامجك توقف بسبب رسالة او بسبب تحميل ملفات او لأي سبب اخرى فإن النقاط التي توقف فيها البرنامج لا يمكن ان يتجاوزها وتخيل هناك مهام لا يجب ان تتوقف بل يجب ان تعمل بمجرد عمل التطبيق وقد تلاحظ ذلك عند بداية تشغيل البرنامج وتحميله لأول مرة عموما دعنا نعرف مالحل

ان المعالجات الحديثة تمكن لك اجراء اكثر من تطبيق في نفس الوقت فالمعالج ينقسم ولا يبالي بما يحدث في الآخر اظنك لقد تنبأت بالحل …..

نعم الحل هو ان تقسم عمل البرنامج في اقسام المعالج وهذا ما سوف نتعرف عليه في هذا الفصل عبر 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( const QString &text ) : QThread(){m_text = text;}

دالة البناء وتقوم بتهيئة المتغير m_text .





while( !stopThreads ){



qDebug() << m_text;



sleep( 1 );}



}
void TextThread::run(){

وهذه دالة عمل المعالج وسوف تبدأ بالشغل عند استدعاء الأمر 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 بشكل تلقائي.

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

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

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

تم تعديل بواسطه GamingMasteR
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

3 إجابة على هذا السؤال .

  • 0

أهلا بك أخي محمد العبدلي , موضوع جيد :thumb_up: .

بالنسبة لتنسيق الصفحة فلا تستخدم المحرر المتقدم المرات القادمة ان شاء الله .

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

رائع, هذه الطريقة تستخدم مع ال Threads لحفاظ على ما يسمى ي Data Consistency و صحة المعلومات الموجودة في المتغيرات على مبدأ Mutual execlusion

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

موضوع مهم وجميل .. سأخزنه على جهازي .. سأحتاجه يوما ما ..

جزاك الله خير .

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .