التزامن(2) لقد تكلمنا عن التزامن في مقال سابق ولكن مع Qmutex لقد تعرفنا كيف يمكن قفله وكيف يمكن فتحه هي بذلك تمثل اشارة مرور للمعالج. حديثنا اليوم يشابه لحد بعيد حديث الأمس ولكن م QReadWriteLock انت في الحقيقة لا تعرف ماذا يقرأ وماذا يكتب ولكن كل ماعليك معرفته ان اقفال الكتابة يقفل الوصول بواسطة القراءة والكتابة ولكن اقفال القارئ يقفل الوصول للكتابة فقط وهذا ما سوف تلاحظه في المثال القادم . ملاحظة: اذا كانت العملية سوف توقف المعالج فلا تستخدم الدالة wait للمعالج للإقفال لأن البرنامج لن يقفل وقتها . وهناك صفوف تستقبل مؤشر ل QReadWriteLock وتسمى بصفوفة الإقفال المؤقت بمجرد تدمير احد هذه الصفوف سوف يفتح القاراءة والكتابة بشكل تلقائي وهي QWriteLocker & QReadLocker عموما سوف يوضح لك المثال أمورا أكثر ولكن لماذا نحتاج الى هكذا عمل ؟؟؟؟؟ دعنا نفرض انك انشأت متغير ولديك معالجين الأول للقراءة والآخر للكتابة فإنك من الطبيعي سوف تطلب الكتابة على المتغير قبل قراءته فلذلك عند اقفال الكتابة يتم اقفال القراءة وثم ان القراءة سوف تقفل الكتابة لأنك لاتريد ان يحدث اضافة للمتغير اثناء قراءتك له مما قد يغير من نتائجك ان هذه هي الفكرة العامة ولن تضح أكثر الا عندما تطلع على المثال التالي
#include <QApplication> #include <QtGui> #include <QtCore> //================================================== ========// QReadWriteLock lock; int m_int=0; bool stopThreads = false; //================================================== ========// class TextThread : public QThread {public:void run();}; //================================================== ========// void TextThread::run(){ while(!stopThreads){ lock.lockForRead(); qDebug() << QString("%1").arg(m_int); sleep( 1 ); lock.unlock(); } } //================================================== ========// class TextThread1 : public QThread {public:void run();}; //================================================== ========// void TextThread1::run(){ while(!stopThreads){ lock.lockForWrite(); m_int++; sleep( 1 ); lock.unlock(); msleep(1); } } //================================================== ========// int main( int argc, char **argv ) { QApplication app( argc, argv ); TextThread foo; TextThread1 bar; foo.start(); bar.start(); QMessageBox::information( 0, "Threading", "Close me to stop!" ); stopThreads = true; foo.wait(); bar.wait(); return 0; }
const int bufferSize = 20; QChar buffer[ bufferSize ]; QSemaphore freeSpace( bufferSize ); QSemaphore availableData( 0 ); bool atEnd = false; QString m_text="mohammed alabdaly is from jeddah";
class TextProducer:public QThread{public:void run();}; //================================================== ========// class TextConsumer:public QThread{public:void run();};
void TextProducer::run(){ for( int i=0; i<m_text.length(); ++i ){ freeSpace.acquire(); buffer[ i % bufferSize ] = m_text[ i ]; if( i == m_text.length()-1 )atEnd = true; availableData.release();}}
void TextConsumer::run(){ int i = 0; while( !atEnd || availableData.available() ){ availableData.acquire(); qDebug() << buffer[ i ]; i = (i+1) % bufferSize; freeSpace.release();}}
int main( int argc, char **argv ){ QApplication app( argc, argv ); TextProducer producer; TextConsumer consumer; producer.start(); consumer.start(); producer.wait(); consumer.wait(); return 0;}
QApplication::instance()->thread()