Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«QT 4: ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ GUI Π½Π° Π‘++Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 97

Автор Жасмин Π‘Π»Π°Π½ΡˆΠ΅Ρ‚

ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρ‡Ρ‚ΠΎ Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΡ‚ΡŒ Π·Π°Ρ‰ΠΈΡ‚Ρƒ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ stopped класса Thread ΠΈΠ· ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π³ΠΎ Ρ€Π°Π·Π΄Π΅Π»Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ QMutex. Π’ΠΎΠ³Π΄Π° ΠΌΡ‹ Π±Ρ‹ Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ ΠΊ классу Thread ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽβ€”Ρ‡Π»Π΅Π½:

private:

QMutex mutex;

…

};

Ѐункция run() измСнилась Π±Ρ‹ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

01 void Thread::run()

02 {

03 forever {

04 mutex.lock();

05 if (stopped) {

06 stopped = false;

07 mutex.unlock();

08 break;

09 }

10 mutex.unlock();

11 cerr << qPrintable(messageStr.ascii);

12 }

13 cerr << endl;

14 }

Ѐункция stop() стала Π±Ρ‹ Ρ‚Π°ΠΊΠΎΠΉ:

01 void Thread::stop()

02 {

03 mutex.lock();

04 stopped = true;

05 mutex.unlock();

06 }

Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° ΠΈ Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠ° Π² слоТных функциях ΠΈΠ»ΠΈ Ρ‚Π°ΠΌ, Π³Π΄Π΅ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ Π‘++, ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ ошибки. Qt ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅Ρ‚ ΡƒΠ΄ΠΎΠ±Π½Ρ‹ΠΉ класс QMutexLocker, ΡƒΠΏΡ€ΠΎΡ‰Π°ΡŽΡ‰ΠΈΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠΎΠ². ΠšΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ‚ΠΎΡ€ QMutexLocker ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π² качСствС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ QMutex ΠΈ Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ Π΅Π³ΠΎ. ДСструктор QMutexLocker Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ. НапримСр, ΠΌΡ‹ ΠΌΠΎΠ³Π»ΠΈ Π±Ρ‹ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹Π΅ Π²Ρ‹ΡˆΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ run() ΠΈ stop() ΠΏΠ΅Ρ€Π΅ΠΏΠΈΡΠ°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

01 void Thread::run()

02 {

03 forever {

04 {

05 QMutexLocker locker(&mutex);

06 if (stopped) {

07 stopped = false;

08 break;

09 }

10 }

11 cerr << qPrintable(messageStr);

12 }

13 cerr << endl;

14 }


15 void Thread::stop()

16 {

17 QMutexLocker locker(&mutex);

18 stopped = true;

18 }

Одна ΠΈΠ· ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ примСнСния ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠΎΠ² Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ ΠΈΠ·-Π·Π° доступности ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°. Π’ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°Ρ… со ΠΌΠ½ΠΎΠ³ΠΈΠΌΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ, ΠΏΡ‹Ρ‚Π°ΡŽΡ‰ΠΈΠΌΠΈΡΡ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ΄Π½Ρƒ ΠΈ Ρ‚Ρƒ ΠΆΠ΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ (Π½Π΅ модифицируя Π΅Π΅), ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠ΅Ρ€ΡŒΠ΅Π·Π½ΠΎ ΡΠ½ΠΈΠΆΠ°Ρ‚ΡŒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ. Π’ этих случаях ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ QReadWriteLock β€” класс синхронизации, Π΄ΠΎΠΏΡƒΡΠΊΠ°ΡŽΡ‰ΠΈΠΉ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΉ доступ для чтСния Π±Π΅Π· сниТСния ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ.

Π’ классС Thread Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ смысла Π·Π°ΠΌΠ΅Π½ΡΡ‚ΡŒ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ QMutex Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΎΠΉ QReadWriteLock для Π·Π°Ρ‰ΠΈΡ‚Ρ‹ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ stopped, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π² Π»ΡƒΡ‡ΡˆΠ΅ΠΌ случаС Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΠΏΠΎΡ‚ΠΎΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ‹Ρ‚Π°Ρ‚ΡŒΡΡ Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ эту ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ Π² любой ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ. Π‘ΠΎΠ»Π΅Π΅ подходящий ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΌΠΎΠ³ Π±Ρ‹ ΡΠΎΡΡ‚ΠΎΡΡ‚ΡŒ ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ»ΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΡΡ‡ΠΈΡ‚Ρ‹Π²Π°ΡŽΡ‰ΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‰ΠΈΡ… доступ ΠΊ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΌ Π΄Π°Π½Π½Ρ‹ΠΌ, ΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ»ΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… Π·Π°ΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‰ΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΡƒΡŽΡ‰ΠΈΡ… Π΄Π°Π½Π½Ρ‹Π΅. НапримСр:

01 MyData data;

02 QReadWriteLock lock;


03 void ReaderThread::run()

04 {

05 …

06 lock.lockForRead();

07 access_data_without_modifying_it(&data);

08 lock.unlock();

09 …

10 }


11 void WriterThread::run()

12 {

13 …

14 lock.lockForWrite();

15 modify_data(&data);

16 lock.unlock();

17 …

18 }

Π Π°Π΄ΠΈ удобства ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ классы QReadLocker ΠΈ QWriteLocker для Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ ΠΈ Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° QReadWriteLock.

Класс QSemaphore β€” это Π΅Ρ‰Π΅ ΠΎΠ΄Π½ΠΎ ΠΎΠ±ΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠ°, Π½ΠΎ, Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΠΊ чтСния/записи, ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ для контроля Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ количСства ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π½Ρ‹Ρ… рСсурсов. Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ Π΄Π²Π° Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° Π΄Π΅ΠΌΠΎΠ½ΡΡ‚Ρ€ΠΈΡ€ΡƒΡŽΡ‚ соотвСтствиС ΠΌΠ΅ΠΆΠ΄Ρƒ QSemaphore ΠΈ QMutex:

β€’ QSemaphore semaphore(1) β€” QMutex mutex,

β€’ Semaphore.acquire() β€” mutex.lock(),

β€’ Semaphore.release() β€” mutex.unlock().

ΠŸΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ 1 конструктору, ΠΌΡ‹ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ сСмафору Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ управляСт Ρ€Π°Π±ΠΎΡ‚ΠΎΠΉ ΠΎΠ΄Π½ΠΎΠ³ΠΎ рСсурса. ΠŸΡ€Π΅ΠΈΠΌΡƒΡ‰Π΅ΡΡ‚Π²ΠΎ примСнСния сСмафора Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ конструктору числа, ΠΎΡ‚Π»ΠΈΡ‡Π½Ρ‹Π΅ ΠΎΡ‚ 1, ΠΈ Π·Π°Ρ‚Π΅ΠΌ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ acquire() нСсколько Ρ€Π°Π· для Π·Π°Ρ…Π²Π°Ρ‚Π° ΠΌΠ½ΠΎΠ³ΠΈΡ… рСсурсов.

Випичная ΠΎΠ±Π»Π°ΡΡ‚ΡŒ примСнСния сСмафоров β€” это ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ количСства Π΄Π°Π½Π½Ρ‹Ρ… (DataSize) ΠΏΡ€ΠΈ совмСстном использовании цикличСского Π±ΡƒΡ„Π΅Ρ€Π° ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° (BufferSize):

const int DataSize = 100000;

const int BufferSize = 4096;

char buffer[BufferSize];

ΠŸΠΎΡ‚ΠΎΠΊ, ΡΠ²Π»ΡΡŽΡ‰ΠΈΠΉΡΡ поставщиком Π΄Π°Π½Π½Ρ‹Ρ…, записываСт Π΄Π°Π½Π½Ρ‹Π΅ Π² Π±ΡƒΡ„Π΅Ρ€, ΠΏΠΎΠΊΠ° ΠΎΠ½ Π½Π΅ заполнится, ΠΈ Π·Π°Ρ‚Π΅ΠΌ повторяСт эту ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρƒ сначала, пСрСписывая ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Π΅. ΠŸΠΎΡ‚ΠΎΠΊ, ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰ΠΈΠΉ Π΄Π°Π½Π½Ρ‹Π΅, считываСт Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎ ΠΌΠ΅Ρ€Π΅ ΠΈΡ… поступлСния. Π­Ρ‚ΠΎ ΠΏΡ€ΠΎΠΈΠ»Π»ΡŽΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Π½ΠΎ Π½Π° рис. 18.2 для нСбольшого 16-Π±Π°ΠΉΡ‚ΠΎΠ²ΠΎΠ³ΠΎ Π±ΡƒΡ„Π΅Ρ€Π°.

Рис. 18.2. МодСль взаимодСйствия Π΄Π²ΡƒΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²: Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΡŽΡ‰Π΅Π³ΠΎ ΠΈ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰Π΅Π³ΠΎ Π΄Π°Π½Π½Ρ‹Π΅.

ΠΠ΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ синхронизации для ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° взаимодСйствия ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², ΠΎΠ΄ΠΈΠ½ ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅Ρ‚ Π΄Π°Π½Π½Ρ‹Π΅, Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΈΡ… считываСт, обусловлСна двумя ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π°ΠΌΠΈ: Ссли Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎΡ‚ΠΎΠΊ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ слишком быстро, ΠΎΠ½ станСт ΠΏΠ΅Ρ€Π΅ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π΅Ρ‰Π΅ Π½Π΅ считал ΠΏΠΎΡ‚ΠΎΠΊβ€”ΠΏΡ€ΠΈΠ΅ΠΌΠ½ΠΈΠΊ; Ссли ΠΏΠΎΡ‚ΠΎΠΊβ€”ΠΏΡ€ΠΈΠ΅ΠΌΠ½ΠΈΠΊ считываСт Π΄Π°Π½Π½Ρ‹Π΅ слишком быстро, ΠΎΠ½ ΠΏΠ΅Ρ€Π΅Π³ΠΎΠ½ΠΈΡ‚ Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊ ΠΈ станСт ΡΡ‡ΠΈΡ‚Ρ‹Π²Π°Ρ‚ΡŒ «мусор».

Π“Ρ€ΡƒΠ±Ρ‹ΠΉ способ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ этой ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ состоит Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ сначала Π·Π°ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ Π±ΡƒΡ„Π΅Ρ€ ΠΈ Π·Π°Ρ‚Π΅ΠΌ ΠΆΠ΄Π°Ρ‚ΡŒ, ΠΏΠΎΠΊΠ° ΠΏΠΎΡ‚ΠΎΠΊβ€”ΠΏΡ€ΠΈΠ΅ΠΌΠ½ΠΈΠΊ Π½Π΅ считаСт Π±ΡƒΡ„Π΅Ρ€ Ρ†Π΅Π»ΠΈΠΊΠΎΠΌ ΠΈ Ρ‚Π°ΠΊ Π΄Π°Π»Π΅Π΅. Однако Π² многопроцСссорных систСмах это Π½Π΅ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ ΠΎΠ±ΠΎΠΈΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ с Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ частями Π±ΡƒΡ„Π΅Ρ€Π°.

Одни ΠΈΠ· эффСктивных способов Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ этой ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² использовании Π΄Π²ΡƒΡ… сСмафоров:

QSemaphore freeSpace(BufferSize);

QSemaphore usedSpace(0);

Π‘Π΅ΠΌΠ°Ρ„ΠΎΡ€ freeSpace управляСт Ρ‚ΠΎΠΉ Ρ‡Π°ΡΡ‚ΡŒΡŽ Π±ΡƒΡ„Π΅Ρ€Π°, которая ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ, Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΌ Π΄Π°Π½Π½Ρ‹Π΅. Π‘Π΅ΠΌΠ°Ρ„ΠΎΡ€ usedSpace управляСт Ρ‚ΠΎΠΉ ΠΎΠ±Π»Π°ΡΡ‚ΡŒΡŽ, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΡ‡ΠΈΡ‚Ρ‹Π²Π°Ρ‚ΡŒ ΠΏΠΎΡ‚ΠΎΠΊβ€”ΠΏΡ€ΠΈΠ΅ΠΌΠ½ΠΈΠΊ. Π­Ρ‚ΠΈ Π΄Π²Π΅ области Π²Π·Π°ΠΈΠΌΠ½ΠΎ Π΄ΠΎΠΏΠΎΠ»Π½ΡΡŽΡ‚ Π΄Ρ€ΡƒΠ³ Π΄Ρ€ΡƒΠ³Π°. Π‘Π΅ΠΌΠ°Ρ„ΠΎΡ€ freeSpace устанавливаСтся Π½Π° Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ BufferSize (4096), Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°Ρ…Π²Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ ΠΈΠΌΠ΅Π½Π½ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ количСство рСсурсов. Когда ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ запускаСтся, ΠΏΠΎΡ‚ΠΎΠΊ, ΡΡ‡ΠΈΡ‚Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ Π΄Π°Π½Π½Ρ‹Π΅, Π½Π°Ρ‡ΠΈΠ½Π°Π΅Ρ‚ Π·Π°Ρ…Π²Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ «свободныС» Π±Π°ΠΉΡ‚Ρ‹ ΠΈ ΠΏΡ€Π΅Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ ΠΈΡ… Π² Β«ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅Β» Π±Π°ΠΉΡ‚Ρ‹. Π‘Π΅ΠΌΠ°Ρ„ΠΎΡ€ usedSpace инициализируСтся Π½ΡƒΠ»Π΅Π²Ρ‹ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΡ‚ΠΎΠΊβ€”ΠΏΡ€ΠΈΠ΅ΠΌΠ½ΠΈΠΊ Π½Π΅ ΠΌΠΎΠ³ ΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ «мусор» ΠΏΡ€ΠΈ запускС прилоТСния.

Π’ этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Π±Π°ΠΉΡ‚ рассматриваСтся ΠΊΠ°ΠΊ ΠΎΠ΄ΠΈΠ½ рСсурс. Π’ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΌ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ ΠΌΡ‹, вСроятно, использовали Π±Ρ‹ Π±ΠΎΠ»Π΅Π΅ ΠΊΡ€ΡƒΠΏΠ½Ρ‹Π΅ Π±Π»ΠΎΠΊΠΈ памяти (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΏΠΎ 64 ΠΈΠ»ΠΈ 256 Π±Π°ΠΉΡ‚) для сниТСния Π·Π°Ρ‚Ρ€Π°Ρ‚, обусловлСнных ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ сСмафоров.

01 void Producer::run()

02 {

03 for (int i = 0; i < DataSize; ++i) {

04 freeSpace.acquire();

05 buffer[i % BufferSize] = "ACGT"[uint(rand()) % 4];

06 usedSpace.release();

07 }

08 }

КаТдая итСрация ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠ°, Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΡŽΡ‰Π΅Π³ΠΎ Π΄Π°Π½Π½Ρ‹Π΅, начинаСтся с Π·Π°Ρ…Π²Π°Ρ‚Π° ΠΎΠ΄Π½ΠΎΠ³ΠΎ «свободного» Π±Π°ΠΉΡ‚Π°. Если вСсь Π±ΡƒΡ„Π΅Ρ€ Π·Π°ΠΏΠΎΠ»Π½Π΅Π½ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ считаны ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌβ€”ΠΏΡ€ΠΈΠ΅ΠΌΠ½ΠΈΠΊΠΎΠΌ, Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ acquire() Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ сСмафор Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° ΠΏΠΎΡ‚ΠΎΠΊβ€”ΠΏΡ€ΠΈΠ΅ΠΌΠ½ΠΈΠΊ Π½Π΅ Π½Π°Ρ‡Π½Π΅Ρ‚ ΡΡ‡ΠΈΡ‚Ρ‹Π²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅. Π—Π°Ρ…Π²Π°Ρ‚ΠΈΠ² Π±Π°ΠΉΡ‚, ΠΌΡ‹ заполняСм Π΅Π³ΠΎ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ случайным Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ («А», Β«Π‘Β», Β«GΒ» ΠΈΠ»ΠΈ Β«TΒ») ΠΈ Π·Π°Ρ‚Π΅ΠΌ освобоТдаСм Π±Π°ΠΉΡ‚ ΠΈ ΠΏΠΎΠΌΠ΅Ρ‡Π°Π΅ΠΌ Π΅Π³ΠΎ ΠΊΠ°ΠΊ Β«ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉΒ», Ρ‚Π΅ΠΌ самым указывая Π½Π° Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Π΅Π³ΠΎ считывания ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌβ€”ΠΏΡ€ΠΈΠ΅ΠΌΠ½ΠΈΠΊΠΎΠΌ.

01 void Consumer::run()

02 {

03 for (int i = 0; i < DataSize; ++i) {

04 usedSpace.acquire();

05 cerr << buffer[i % BufferSize];

06 freeSpace.release();

07 }

08 cerr << endl;

09 }

Π Π°Π±ΠΎΡ‚Ρƒ ΠΏΠΎΡ‚ΠΎΠΊΠ°β€”ΠΏΡ€ΠΈΠ΅ΠΌΠ½ΠΈΠΊΠ° ΠΌΡ‹ Π½Π°Ρ‡ΠΈΠ½Π°Π΅ΠΌ с Π·Π°Ρ…Π²Π°Ρ‚Π° ΠΎΠ΄Π½ΠΎΠ³ΠΎ «использованного» Π±Π°ΠΉΡ‚Π°. Если Π±ΡƒΡ„Π΅Ρ€ Π½Π΅ содСрТит Π΄Π°Π½Π½Ρ‹Ρ… для чтСния, Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ acquire() Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ сСмафор Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π½Π΅ сформируСт ΠΊΠ°ΠΊΠΈΠ΅-Ρ‚ΠΎ Π΄Π°Π½Π½Ρ‹Π΅. ПослС Π·Π°Ρ…Π²Π°Ρ‚Π° Π½Π°ΠΌΠΈ Π±Π°ΠΉΡ‚Π° ΠΌΡ‹ Π²Ρ‹Π²ΠΎΠ΄ΠΈΠΌ Π΅Π³ΠΎ Π½Π° экран ΠΈ освобоТдаСм Π±Π°ΠΉΡ‚, помСчая Π΅Π³ΠΎ ΠΊΠ°ΠΊ «свободный», Ρ‚Π΅ΠΌ самым позволяя ΠΏΠ΅Ρ€Π²ΠΎΠΌΡƒ ΠΏΠΎΡ‚ΠΎΠΊΡƒ вновь ΠΏΡ€ΠΈΡΠ²ΠΎΠΈΡ‚ΡŒ Π΅ΠΌΡƒ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅.

01 int main()

02 {

03 Producer producer;

04 Consumer consumer;

05 producer.start();

06 consumer.start();

07 producer.wait();

08 consumer.wait();

09 return 0;

10 }

НаконСц, Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ main() ΠΌΡ‹ запускаСм ΠΎΠ±Π° ΠΏΠΎΡ‚ΠΎΠΊΠ°. ПослС этого происходит ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅: ΠΏΠΎΡ‚ΠΎΠΊ, Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ Π΄Π°Π½Π½Ρ‹Π΅, ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ «свободноС» пространство Π² «использованноС», послС Ρ‡Π΅Π³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊβ€”ΠΏΡ€ΠΈΠ΅ΠΌΠ½ΠΈΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ Π΅Π³ΠΎ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ΅ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ Π² «свободноС» пространство.

Когда ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° выполняСтся, ΠΎΠ½Π° Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ Π½Π° консоль ΡΠ»ΡƒΡ‡Π°ΠΉΠ½ΡƒΡŽ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΈΠ· 100 000 Π±ΡƒΠΊΠ² «А», Β«Π‘Β», Β«GΒ» ΠΈ Β«TΒ» ΠΈ Π·Π°Ρ‚Π΅ΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ свою Ρ€Π°Π±ΠΎΡ‚Ρƒ. Для Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ½ΡΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ происходит Π½Π° самом Π΄Π΅Π»Π΅, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Π²Ρ‹Π²ΠΎΠ΄ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΈ вмСсто этого Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ΡŒ Π½Π° консоль Π±ΡƒΠΊΠ²Ρƒ Β«PΒ» ΠΏΡ€ΠΈ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π±Π°ΠΉΡ‚Π° ΠΏΠ΅Ρ€Π²Ρ‹ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ ΠΈ Π±ΡƒΠΊΠ²Ρƒ «с» ΠΏΡ€ΠΈ Ρ‡Ρ‚Π΅Π½ΠΈΠΈ Π±Π°ΠΉΡ‚Π° Π²Ρ‚ΠΎΡ€Ρ‹ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ. И Ρ€Π°Π΄ΠΈ максимального упрощСния ситуации ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ мСньшиС значСния ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² DataSize ΠΈ BufferSize.