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

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

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

НапримСр, ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, ΠΊΠΎΠ³Π΄Π° DataSize Ρ€Π°Π²Π΅Π½ 10 ΠΈ BufferSize Ρ€Π°Π²Π΅Π½ 4, Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Ρ‚Π°ΠΊΠΈΠΌ: Β«PcPcPcPcPcPcPcPcPcPcΒ». Π’ Π΄Π°Π½Π½ΠΎΠΌ случаС ΠΏΠΎΡ‚ΠΎΠΊβ€”ΠΏΡ€ΠΈΠ΅ΠΌΠ½ΠΈΠΊ считываСт Π±Π°ΠΉΡ‚Ρ‹ сразу ΠΏΠΎ ΠΌΠ΅Ρ€Π΅ ΠΈΡ… формирования ΠΏΠ΅Ρ€Π²Ρ‹ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ; ΠΎΠ±Π° ΠΏΠΎΡ‚ΠΎΠΊΠ° Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ Π½Π° ΠΎΠ΄Π½ΠΎΠΉ скорости. Π’ Π΄Ρ€ΡƒΠ³ΠΎΠΌ случаС ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ Π±ΡƒΡ„Π΅Ρ€ Ρ†Π΅Π»ΠΈΠΊΠΎΠΌ Π΅Ρ‰Π΅ Π΄ΠΎ Π½Π°Ρ‡Π°Π»Π° Π΅Π³ΠΎ считывания Π²Ρ‚ΠΎΡ€Ρ‹ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ: Β«PPPPccccPPPPccccPPccΒ». БущСствуСт ΠΌΠ½ΠΎΠ³ΠΎ Π΄Ρ€ΡƒΠ³ΠΈΡ… Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ². Π‘Π΅ΠΌΠ°Ρ„ΠΎΡ€Ρ‹ Π΄Π°ΡŽΡ‚ Π±ΠΎΠ»ΡŒΡˆΡƒΡŽ свободу дСйствий ΠΏΠ»Π°Π½ΠΈΡ€ΠΎΠ²Ρ‰ΠΈΠΊΠ°ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Π² спСцифичСских систСмах, Ρ‡Ρ‚ΠΎ позволяСт ΠΈΠΌ, ΠΈΠ·ΡƒΡ‡ΠΈΠ² ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², Π²Ρ‹Π±Ρ€Π°Ρ‚ΡŒ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΡΡ‰ΡƒΡŽ ΠΏΠΎΠ»ΠΈΡ‚ΠΈΠΊΡƒ планирования ΠΈΡ… Ρ€Π°Π±ΠΎΡ‚Ρ‹.

Π”Ρ€ΡƒΠ³ΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ ΠΊ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡŽ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ синхронизации Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΏΠΎΡ‚ΠΎΠΊΠ°, Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΡŽΡ‰Π΅Π³ΠΎ Π΄Π°Π½Π½Ρ‹Π΅, ΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠ°, ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰Π΅Π³ΠΎ Π΄Π°Π½Π½Ρ‹Π΅, состоит Π² ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠΈ классов QWaitCondition ΠΈ QMutex. Класс QWaitCondition позволяСт ΠΎΠ΄Π½ΠΎΠΌΡƒ ΠΏΠΎΡ‚ΠΎΠΊΡƒ Β«ΠΏΡ€ΠΎΠ±ΡƒΠΆΠ΄Π°Ρ‚ΡŒΒ» Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠΈ, ΠΊΠΎΠ³Π΄Π° удовлСтворяСтся Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ условиС. Π­Ρ‚ΠΈΠΌ обСспСчиваСтся Π±ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΡ‡Π½ΠΎΠ΅ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅, Ρ‡Π΅ΠΌ ΠΏΡƒΡ‚Π΅ΠΌ примСнСния Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½ΠΈΡ… ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠΎΠ². Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ, ΠΊΠ°ΠΊ это Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚, ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Π΄Π΅Π»Π°Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ с двумя ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ условия оТидания.

const int DataSize = 100000;

const int BufferSize = 4096;

char buffer[BufferSize];

QWaitCondition bufferIsNotFull;

QWaitCondition bufferIsNotEmpty;

QMutex mutex;

int usedSpace = 0;

ΠšΡ€ΠΎΠΌΠ΅ Π±ΡƒΡ„Π΅Ρ€Π° ΠΌΡ‹ объявляСм Π΄Π²Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° QWaitCondition, ΠΎΠ΄ΠΈΠ½ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ QMutex ΠΈ ΠΎΠ΄Π½Ρƒ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ для хранСния количСства Β«ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½Π½Ρ‹Ρ…Β» Π±Π°ΠΉΡ‚ΠΎΠ² Π² Π±ΡƒΡ„Π΅Ρ€Π΅.

01 void Producer::run()

02 {

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

04 mutex.lock();

05 while (usedSpace == BufferSize)

06 bufferIsNotFull.wait(&mutex);

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

08 ++usedSpace;

09 bufferIsNotEmpty.wakeAll();

10 mutex.unlock();

11 }

12 }

Π Π°Π±ΠΎΡ‚Ρƒ ΠΏΠΎΡ‚ΠΎΠΊΠ°, Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΡŽΡ‰Π΅Π³ΠΎ Π΄Π°Π½Π½Ρ‹Π΅, ΠΌΡ‹ Π½Π°Ρ‡ΠΈΠ½Π°Π΅ΠΌ с ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ заполнСния Π±ΡƒΡ„Π΅Ρ€Π°. Если ΠΎΠ½ Π·Π°ΠΏΠΎΠ»Π½Π΅Π½, ΠΌΡ‹ ΠΆΠ΄Π΅ΠΌ возникновСния условия Β«Π±ΡƒΡ„Π΅Ρ€ Π½Π΅ Π·Π°ΠΏΠΎΠ»Π½Π΅Π½Β». Когда это условиС удовлСтворяСтся, ΠΌΡ‹ записываСм ΠΎΠ΄ΠΈΠ½ Π±Π°ΠΉΡ‚ Π² Π±ΡƒΡ„Π΅Ρ€, ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Ρƒ usedSpace ΠΈ возобновляСм Ρ€Π°Π±ΠΎΡ‚Ρƒ любого ΠΏΠΎΡ‚ΠΎΠΊΠ°, ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰Π΅Π³ΠΎ возникновСния условия Β«Π±ΡƒΡ„Π΅Ρ€ Π½Π΅ пустой».

ΠœΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ для контроля любого доступа ΠΊ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ usedSpace. Ѐункция QWaitCondition::wait() ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ Π² ΠΏΠ΅Ρ€Π²ΠΎΠΌ своСм Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π΅ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΠ½Π° ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΎΠΉ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ° ΠΈ Π·Π°Ρ‚Π΅ΠΌ вновь Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ Π΅Π³ΠΎ ΠΏΠ΅Ρ€Π΅Π΄ Π²Ρ‹Ρ…ΠΎΠ΄ΠΎΠΌ.

Π’ этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΌΡ‹ ΠΌΠΎΠ³Π»ΠΈ Π±Ρ‹ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Ρ†ΠΈΠΊΠ» while

while (usedSpace == BufferSize)

bufferIsNotFull.wait(&mutex);

Π½Π° ΠΈΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡŽ if:

if (usedSpace == BufferSize) {

mutex.unlock();

bufferIsNotFull.wait();

mutex.lock();

}

Однако это Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ, ΠΊΠ°ΠΊ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΌΡ‹ станСм ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ нСсколько ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΡŽΡ‰ΠΈΡ… Π΄Π°Π½Π½Ρ‹Π΅, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π΄Ρ€ΡƒΠ³ΠΎΠΉ Ρ‚Π°ΠΊΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°Ρ…Π²Π°Ρ‚ΠΈΡ‚ΡŒ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ сразу ΠΆΠ΅ послС Π²Ρ‹Π·ΠΎΠ²Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ wait() ΠΈ вновь ΠΎΡ‚ΠΌΠ΅Π½ΠΈΡ‚ΡŒ условиС Β«Π±ΡƒΡ„Π΅Ρ€ Π½Π΅ Π·Π°ΠΏΠΎΠ»Π½Π΅Π½Β».

01 void Consumer::run()

02 {

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

04 mutex.lock();

05 while (usedSpace == 0)

06 bufferIsNotEmpty.wait(&mutex);

07 cerr << buffer[i % BufferSize];

08 --usedSpace;

09 bufferIsNotFull.wakeAll();

10 mutex.unlock();

11 }

12 cerr << endl;

13 }

ΠŸΠΎΡ‚ΠΎΠΊβ€”ΠΏΡ€ΠΈΠ΅ΠΌΠ½ΠΈΠΊ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π² точности Π½Π°ΠΎΠ±ΠΎΡ€ΠΎΡ‚ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°: ΠΎΠ½ ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚ возникновСния условия Β«Π±ΡƒΡ„Π΅Ρ€ Π½Π΅ пустой» ΠΈ возобновляСт Ρ€Π°Π±ΠΎΡ‚Ρƒ любого ΠΏΠΎΡ‚ΠΎΠΊΠ°, ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰Π΅Π³ΠΎ условия Β«Π±ΡƒΡ„Π΅Ρ€ Π½Π΅ Π·Π°ΠΏΠΎΠ»Π½Π΅Π½Β».

Π’ΠΎ всСх ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΠΌΡ‹Ρ… Π΄ΠΎ сих ΠΏΠΎΡ€ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°Ρ… наши ΠΏΠΎΡ‚ΠΎΠΊΠΈ ΠΈΠΌΠ΅ΡŽΡ‚ доступ ΠΊ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹ΠΌ Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌ. Но для Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½Ρ‹Ρ… ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ трСбуСтся Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Π² Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Ρ… ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… Π½Π΅ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ для Ρ€Π°Π·Π½Ρ‹Ρ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ². Π­Ρ‚ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ часто Π½Π°Π·Ρ‹Π²Π°ΡŽΡ‚ локальной ΠΏΠ°ΠΌΡΡ‚ΡŒΡŽ ΠΏΠΎΡ‚ΠΎΠΊΠ° (thread-local storage β€” TLS) ΠΈΠ»ΠΈ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΌΠΈ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠ° (thread-specific data β€” TSD). ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Β«ΡΡ…ΠΈΡ‚Ρ€ΠΈΡ‚ΡŒΒ» ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅, Π² качСствС ΠΊΠ»ΡŽΡ‡Π΅ΠΉ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Ρ‹ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² (Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ QThread::currentThread()), Π½ΠΎ Π±ΠΎΠ»Π΅Π΅ ΠΏΡ€ΠΈΠ²Π»Π΅ΠΊΠ°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ состоит Π² использовании класса QThreadStorage<T>.

ΠžΠ±Ρ‹Ρ‡Π½ΠΎ класс QThreadStorage<T> ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для ΠΊΡΡˆβ€”ΠΏΠ°ΠΌΡΡ‚ΠΈ. ИмСя ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ кэш для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°, ΠΌΡ‹ ΠΈΠ·Π±Π΅Π³Π°Π΅ΠΌ Π·Π°Ρ‚Ρ€Π°Ρ‚, связанных с Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΎΠΉ, Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΎΠΉ ΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹ΠΌ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ΠΌ освобоТдСния ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠ°. НапримСр:

01 QThreadStorage<QHash<int, double> *> cache;

02 void insertIntoCache(int id, double value)

03 {

04 if (!cache.hasLocalData())

05 cache.setLocalData(new QHash<int, double>);

06 cache.localData()->insert(id, value);

07 }


08 void removeFromCache(int id)

09 {

10 if (cache.hasLocalData())

11 cache.localData()->remove(id);

12 }

ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ cache содСрТит ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ QHash<int, double>. (Из-Π·Π° ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ с Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ компиляторами Ρ‚ΠΈΠΏ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, Π·Π°Π΄Π°Π²Π°Π΅ΠΌΡ‹ΠΉ Π² шаблонном классС QThreadStorage<T>, Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΌ.) ΠŸΡ€ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠΈ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ Ρ€Π°Π· кэша Π² ΠΏΠΎΡ‚ΠΎΠΊΠ΅ функция hasLocalData() Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ false, ΠΈ ΠΌΡ‹ создаСм ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Ρ‚ΠΈΠΏΠ° QHash<int, double>.

ΠšΡ€ΠΎΠΌΠ΅ ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ класс QThreadStorage<T> ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ для Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Ρ… ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…, ΠΎΡ‚Ρ€Π°ΠΆΠ°ΡŽΡ‰ΠΈΡ… состояниС ошибки (ΠΏΠΎΠ΄ΠΎΠ±Π½Ρ‹Ρ… errno), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ΅ Π½Π΅ влияли Π½Π° Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠΈ.

ВзаимодСйствиС с Π³Π»Π°Π²Π½Ρ‹ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ

ΠŸΡ€ΠΈ запускС прилоТСния Qt Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΠΏΠΎΡ‚ΠΎΠΊ β€” Π³Π»Π°Π²Π½Ρ‹ΠΉ. Волько этот ΠΏΠΎΡ‚ΠΎΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ QApplication ΠΈΠ»ΠΈ QCoreApplication ΠΈ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ для Π½Π΅Π³ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ exec(). ПослС Π²Ρ‹Π·ΠΎΠ²Π° exec() этот ΠΏΠΎΡ‚ΠΎΠΊ Π»ΠΈΠ±ΠΎ ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚ возникновСния ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ события, Π»ΠΈΠ±ΠΎ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ ΠΊΠ°ΠΊΠΎΠ΅-Π½ΠΈΠ±ΡƒΠ΄ΡŒ событиС.

Π“Π»Π°Π²Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ Π½ΠΎΠ²Ρ‹Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠΈ, создавая ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ подкласса QThread, ΠΊΠ°ΠΊ ΠΌΡ‹ это Π΄Π΅Π»Π°Π»ΠΈ Π² ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΌ Ρ€Π°Π·Π΄Π΅Π»Π΅. Если эти Π½ΠΎΠ²Ρ‹Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Π΄Ρ€ΡƒΠ³ с Π΄Ρ€ΡƒΠ³ΠΎΠΌ, ΠΎΠ½ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΏΠΎΠ΄ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ΠΌ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠΎΠ², Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΠΊ чтСния/записи, сСмафоров ΠΈΠ»ΠΈ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Ρ… событий. Но Π½ΠΈ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· этих ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² нСльзя ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для связи с Π³Π»Π°Π²Π½Ρ‹ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ½ΠΈ Π±ΡƒΠ΄ΡƒΡ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ†ΠΈΠΊΠ» ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ событий ΠΈ «заморозят» интСрфСйс ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ.

Для связи Π²Ρ‚ΠΎΡ€ΠΈΡ‡Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ° с Π³Π»Π°Π²Π½Ρ‹ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠ΅ΠΆΠΏΠΎΡ‚ΠΎΡ‡Π½Ρ‹Π΅ соСдинСния сигнал—слот. ΠžΠ±Ρ‹Ρ‡Π½ΠΎ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ сигналов ΠΈ слотов Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ синхронно, Ρ‚.Π΅. связанный с сигналом слот вызываСтся сразу послС Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ сигнала, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ прямой Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ.

Однако ΠΊΠΎΠ³Π΄Π° Π²Ρ‹ связываСтС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, Β«ΠΆΠΈΠ²ΡƒΡ‰ΠΈΠ΅Β» Π² Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠ°Ρ…, ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ взаимодСйствия сигналов ΠΈ слотов становится асинхронным. (Π’Π°ΠΊΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ пятого ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ QObject::connect().) Π’Π½ΡƒΡ‚Ρ€ΠΈ эти связи Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‚ΡΡ ΠΏΡƒΡ‚Π΅ΠΌ рСгистрации события. Π‘Π»ΠΎΡ‚ Π·Π°Ρ‚Π΅ΠΌ вызываСтся Π² Ρ†ΠΈΠΊΠ»Π΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ событий ΠΏΠΎΡ‚ΠΎΠΊΠ°, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ находится ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ получатСля. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ QObject сущСствуСт Π² ΠΏΠΎΡ‚ΠΎΠΊΠ΅, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΎΠ½ Π±Ρ‹Π» создан; Π² любой ΠΌΠΎΠΌΠ΅Π½Ρ‚ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ располоТСниС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π²Ρ‹Π·ΠΎΠ²Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ QObject::moveToThread().

Рис. 18.3. ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Image Pro.

Для ΠΈΠ»Π»ΡŽΡΡ‚Ρ€Π°Ρ†ΠΈΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ соСдинСний сигнал—слот с Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ ΠΌΡ‹ рассмотрим ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ ΠΊΠΎΠ΄ прилоТСния Image Pro β€” процСссора ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ, ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΠ²Π°ΡŽΡ‰Π΅Π³ΠΎ Π±Π°Π·ΠΎΠ²Ρ‹Π΅ возмоТности ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰Π΅Π³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Ρ‚ΡŒ, ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΈ Ρ†Π²Π΅Ρ‚ изобраТСния. Π’ Π΄Π°Π½Π½ΠΎΠΌ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΎΠ΄ΠΈΠ½ Π²Ρ‚ΠΎΡ€ΠΈΡ‡Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ для выполнСния ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ Π½Π°Π΄ изобраТСниями Π±Π΅Π· Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ Ρ†ΠΈΠΊΠ»Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ событий. Π­Ρ‚ΠΎ ΠΈΠΌΠ΅Π΅Ρ‚ сущСствСнноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ ΠΎΡ‡Π΅Π½ΡŒ большого Ρ€Π°Π·ΠΌΠ΅Ρ€Π°. Π’Ρ‚ΠΎΡ€ΠΈΡ‡Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ ΠΈΠΌΠ΅Π΅Ρ‚ список выполняСмых Π·Π°Π΄Π°Ρ‡ ΠΈΠ»ΠΈ Β«Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉΒ», ΠΈ ΠΎΠ½ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ события для Π³Π»Π°Π²Π½ΠΎΠ³ΠΎ ΠΎΠΊΠ½Π°, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠΎΠΎΠ±Ρ‰Π°Ρ‚ΡŒ ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ ΠΈΠ΄Π΅Ρ‚ процСсс ΠΈΡ… выполнСния.

01 ImageWindow::ImageWindow()

02 {

03 imageLabel = new QLabel;

04 imageLabel->setBackgroundRole(QPalette::Dark);

05 imageLabel->setAutoFillBackground(true);

06 imageLabel->setAlignment(Qt::AlignLeft | Qt::AlignTop);

07 setCentralWidget(imageLabel);

08 createActions();

09 createMenus();

10 statusBar()->showMessage(tr("Ready"), 2000);

11 connect(&thread, SIGNAL(transactionStarted(const QString &)),

12 statusBar(), SLOT(showMessage(const QString &)));

13 connect(&thread, SIGNAL(finished()),

14 this, SLOT(allTransactionsDone()));

15 setCurrentFile("");

16 }

Π˜Π½Ρ‚Π΅Ρ€Π΅ΡΠ½ΠΎΠΉ Ρ‡Π°ΡΡ‚ΡŒΡŽ конструктора ImageWindow ΡΠ²Π»ΡΡŽΡ‚ΡΡ Π΄Π²Π° соСдинСния сигнал—слот. Π’ ΠΎΠ±ΠΎΠΈΡ… случаях сигнал гСнСрируСтся ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ TransactionThread, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΡ‹ вскорС рассмотрим.

01 void ImageWindow::flipHorizontally()