ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΏΡΠΈ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ, ΠΊΠΎΠ³Π΄Π° 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()