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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«C++. Π‘Π±ΠΎΡ€Π½ΠΈΠΊ Ρ€Π΅Ρ†Π΅ΠΏΡ‚ΠΎΠ²Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 111

Автор Π”. БтСфСнс

};


Queue<std::string> queueOfStrings;


void sendSomething() {

 std::string s;

 for (int i = 0; i < 10; ++i) {

  queueOfStrings.enqueue("Cyrus");

 }

}


void recvSomething() {

 std::string s;

 for(int i = 0; i < 10; ++i) {

  try {

   s = queueOfStrings.dequeue();

  } catch(...) {}

 }

}


int main() {

 boost::thread thr1(sendSomething);

 boost::thread thr2(recvSomething);

 thr1.join();

 thr2.join();

}

ΠžΠ±ΡΡƒΠΆΠ΄Π΅Π½ΠΈΠ΅

ΠžΠ±Π΅ΡΠΏΠ΅Ρ‡Π΅Π½ΠΈΠ΅ потокозащищСнности классов, Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, Π±Π»ΠΎΠΊΠΎΠ² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² являСтся ΡΡƒΡ‰Π½ΠΎΡΡ‚ΡŒΡŽ ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠ³ΠΎ программирования. Если Π²Ρ‹ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈΡ€ΡƒΠ΅Ρ‚Π΅ ΠΊΠ°ΠΊΠΎΠΉ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ обСспСчСния с возмоТностями ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ, Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠΎΡΡ‚Π°Ρ€Π°Ρ‚ΡŒΡΡ ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΡ‚ΡŒ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ своим Π½Π°Π±ΠΎΡ€ΠΎΠΌ рСсурсов, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ Π² стСкС ΠΈ динамичСской памяти, рСсурсами ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΉ систСмы ΠΈ Ρ‚.Π΄. Однако Ρ€Π°Π½ΠΎ ΠΈΠ»ΠΈ ΠΏΠΎΠ·Π΄Π½ΠΎ Π²Π°ΠΌ придСтся ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΡ‚ΡŒ совмСстноС использованиС Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ ΠΊΠ°ΠΊΠΈΡ…-Π»ΠΈΠ±ΠΎ рСсурсов. Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ совмСстная ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ ΠΏΠΎΡΡ‚ΡƒΠΏΠ°ΡŽΡ‰ΠΈΡ… запросов (ΠΊΠ°ΠΊ это происходит Π½Π° ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠΌ Π²Π΅Π±-сСрвСрС) ΠΈΠ»ΠΈ Π½Π΅Ρ‡Ρ‚ΠΎ достаточно простоС, ΠΊΠ°ΠΊ ΠΏΠΎΡ‚ΠΎΠΊ Π²Ρ‹Π²ΠΎΠ΄Π° (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π² Ρ„Π°ΠΉΠ» ΠΆΡƒΡ€Π½Π°Π»Π° ΠΈΠ»ΠΈ Π΄Π°ΠΆΠ΅ Π² cout). Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚Π½Ρ‹ΠΉ способ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ†ΠΈΠΈ бСзопасного совмСстного использования рСсурсов ΠΏΠΎΠ΄Ρ€Π°Π·ΡƒΠΌΠ΅Π²Π°Π΅Ρ‚ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠ° (mutex), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ обСспСчиваСт ΠΌΠΎΠ½ΠΎΠΏΠΎΠ»ΡŒΠ½Ρ‹ΠΉ доступ ΠΊ Ρ‡Π΅ΠΌΡƒ-Π»ΠΈΠ±ΠΎ.

ΠžΡΡ‚Π°Π»ΡŒΠ½Π°Ρ Ρ‡Π°ΡΡ‚ΡŒ обсуТдСния Π² Ρ†Π΅Π»ΠΎΠΌ посвящСна ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠ°ΠΌ, ΠΈ Π² частности ΠΌΠ΅Ρ‚ΠΎΠ΄Π°ΠΌ использования boost::mutex для сСриализации доступа ΠΊ рСсурсам. Π― ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽ Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΎΠ»ΠΎΠ³ΠΈΡŽ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π° «концСпция/модСль», ΠΎ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ я Π³ΠΎΠ²ΠΎΡ€ΠΈΠ» ΠΊΡ€Π°Ρ‚ΠΊΠΎ Π²ΠΎ Π²Π²Π΅Π΄Π΅Π½ΠΈΠΈ настоящСй Π³Π»Π°Π²Ρ‹. ΠšΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΡ β€” это абстрактноС (нСзависимоС ΠΎΡ‚ языка) описаниС Ρ‡Π΅Π³ΠΎ-Π»ΠΈΠ±ΠΎ, Π° модСль ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΠΈ β€” ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ΅ Π΅Π΅ прСдставлСниС Π² Ρ„ΠΎΡ€ΠΌΠ΅ класса Π‘++. Π£Ρ‚ΠΎΡ‡Π½Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΠΈ β€” это опрСдСлСнная концСпция с Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ возмоТностями.

ВсС-Ρ‚Π°ΠΊΠΈ ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ прСдставляСт собой ΡΠ»ΠΎΠΆΠ½ΡƒΡŽ Ρ‚Π΅ΠΌΡƒ, ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ Ρ€Π΅Ρ†Π΅ΠΏΡ‚Π΅ нСльзя ΠΎΡ‚Ρ€Π°Π·ΠΈΡ‚ΡŒ всС примСняСмыС Π² этой Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹. МоТно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠ½ΠΎΠ³ΠΎ шаблонов проСктирования ΠΈ Ρ€Π°Π·Π½Ρ‹Ρ… стратСгий, подходящих для Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ. Если ΠΏΡ€ΠΈ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ обСспСчСния Π²Ρ‹ ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅Ρ‚Π΅, Ρ‡Ρ‚ΠΎ многопоточная ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° составит Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ объСм, ΠΈΠ»ΠΈ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈΡ€ΡƒΠ΅Ρ‚Π΅ Π²Ρ‹ΡΠΎΠΊΠΎΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ прилоТСния, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ Ρ…ΠΎΡ€ΠΎΡˆΡƒΡŽ ΠΊΠ½ΠΈΠ³Ρƒ ΠΏΠΎ шаблонам ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ. МногиС ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹, связанныС с трудностями ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½Ρ‹Ρ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ, ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ ΠΏΡ€Π΅ΠΎΠ΄ΠΎΠ»Π΅Π½Ρ‹ Π·Π° счСт Ρ‚Ρ‰Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΈ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ проСктирования.

ИспользованиС ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠΎΠ²

ΠšΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΡ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠ° проста: ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ это Π½Π΅ΠΊΠΈΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‰ΠΈΠΉ рСсурс; Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΠΏΠΎΡ‚ΠΎΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ Π΅Π³ΠΎ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΠ»ΠΈ Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π² Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ. Он являСтся Ρ„Π»Π°Π³ΠΎΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ†ΠΈΠΈ доступа ΠΊ рСсурсу со стороны Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ. Π’ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅ Boost Threads модСлью ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΠΈ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠ° являСтся класс boost::mutex. Π’ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ 1 2.2 доступ для записи Π² классС Queue обСспСчиваСтся ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ-Ρ‡Π»Π΅Π½ΠΎΠΌ mutex.

boost::mutex mutex_;

mutex_ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΊΠ°ΠΊΠΎΠΉ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ-Ρ‡Π»Π΅Π½ΠΎΠΌ, которая Π΄ΠΎΠ»ΠΆΠ½Π° ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ состояниС ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ обслуТиваСмых элСмСнтов. Π‘Π°ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ mutex_ Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ Π·Π½Π°Π΅Ρ‚ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ прСдставляСт. Π­Ρ‚ΠΎ просто Ρ„Π»Π°Π³ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ/Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ всСми ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡΠΌΠΈ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ рСсурса.

Π’ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ 12.2, ΠΊΠΎΠ³Π΄Π° какая-Π½ΠΈΠ±ΡƒΠ΄ΡŒ функция-Ρ‡Π»Π΅Π½ класса Queue собираСтся ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ состояниС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, ΠΎΠ½Π° сначала Π΄ΠΎΠ»ΠΆΠ½Π° Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ mutex_. Волько ΠΎΠ΄ΠΈΠ½ ΠΏΠΎΡ‚ΠΎΠΊ Π² ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ Π΅Π³ΠΎ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π½Π΅ позволяСт нСскольким ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ состояниС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Queue. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ mutex прСдставляСт собой простой ΡΠΈΠ³Π½Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ, Π½ΠΎ это Π½Π΅Ρ‡Ρ‚ΠΎ большСС, Ρ‡Π΅ΠΌ просто bool ΠΈΠ»ΠΈ int, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ для mutex Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ сСриализованный доступ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ обСспСчСн Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ядром ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΉ систСмы. Если Π²Ρ‹ ΠΏΠΎΠΏΡ‹Ρ‚Π°Π΅Ρ‚Π΅ΡΡŒ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ‚ΠΎ ΠΆΠ΅ самоС с bool, это Π½Π΅ сработаСт, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π½ΠΈΡ‡Ρ‚ΠΎ Π½Π΅ прСпятствуСт ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ состояния bool нСсколькими ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ. (Π’ Ρ€Π°Π·Π½Ρ‹Ρ… ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Ρ… систСмах это осущСствляСтся ΠΏΠΎ-Ρ€Π°Π·Π½ΠΎΠΌΡƒ, ΠΈ ΠΈΠΌΠ΅Π½Π½ΠΎ поэтому Π½Π΅ просто Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅Π½ΠΎΡΠΈΠΌΡƒΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ².)

ΠžΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ mutex Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‚ΡΡ ΠΈ Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‚ΡΡ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ нСсколько Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… стратСгий Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ, самой простой ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… являСтся Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° scoped_lock. scoped_lock β€” это класс, ΠΏΡ€ΠΈ конструировании ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ Ρ‚ΠΈΠΏΠ° mutex, Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΉ Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΡƒΠ½ΠΈΡ‡Ρ‚ΠΎΠΆΠ΅Π½Π° Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° lock. Рассмотрим Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ-Ρ‡Π»Π΅Π½ enqueue Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ 12.2, которая ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, ΠΊΠ°ΠΊ scoped_lock Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ совмСстно с ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠΎΠΌ mutex_.

void enqueue(const T& x) {

 boost::mutex::scoped_lock lock(mutex_);

 list_.push_back(x);

} // Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΎ!

Когда lock уничтоТаСтся, mutex_ разблокируСтся. Если lock конструируСтся для ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° mutex, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΡƒΠΆΠ΅ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ Π΄Ρ€ΡƒΠ³ΠΈΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ, Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΏΠΎΡ‚ΠΎΠΊ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ Π² состояниС оТидания Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° lock Π½Π΅ окаТСтся доступСн.

Π’Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ ΠΏΠΎΠ½Π°Ρ‡Π°Π»Ρƒ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ странным: Π° ΠΏΠΎΡ‡Π΅ΠΌΡƒ Π±Ρ‹ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΡƒ mutex Π½Π΅ ΠΈΠΌΠ΅Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ lock ΠΈ unlock? ΠŸΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ класса scoped_lock, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ обСспСчиваСт Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ ΠΏΡ€ΠΈ конструировании ΠΈ Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ ΠΏΡ€ΠΈ ΡƒΠ½ΠΈΡ‡Ρ‚ΠΎΠΆΠ΅Π½ΠΈΠΈ, Π½Π° самом Π΄Π΅Π»Π΅ Π±ΠΎΠ»Π΅Π΅ ΡƒΠ΄ΠΎΠ±Π½ΠΎ ΠΈ ΠΌΠ΅Π½Π΅Π΅ ΠΏΠΎΠ΄Π²Π΅Ρ€ΠΆΠ΅Π½ΠΎ ошибкам. Когда Π²Ρ‹ создаСтС Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ scoped_lock, ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ блокируСтся Π½Π° вСсь ΠΏΠ΅Ρ€ΠΈΠΎΠ΄ сущСствования ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° scoped_lock, Ρ‚.Π΅. Π²Π°ΠΌ Π½Π΅ Π½Π°Π΄ΠΎ Π½ΠΈΡ‡Π΅Π³ΠΎ Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π² явной Ρ„ΠΎΡ€ΠΌΠ΅ Π½Π° ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Π²Π΅Ρ‚Π²ΠΈ вычислСний. Π‘ Π΄Ρ€ΡƒΠ³ΠΎΠΉ стороны, Ссли Π²Π°ΠΌ приходится явно Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π·Π°Ρ…Π²Π°Ρ‡Π΅Π½Π½Ρ‹ΠΉ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‚ Π»ΡŽΠ±Ρ‹Ρ… ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π²Ρ‹Π±Ρ€ΠΎΡˆΠ΅Π½Ρ‹ Π² вашСй Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ (ΠΈΠ»ΠΈ Π³Π΄Π΅-Π½ΠΈΠ±ΡƒΠ΄ΡŒ Π²Ρ‹ΡˆΠ΅ Π΅Π΅ Π² стСкС Π²Ρ‹Π·ΠΎΠ²ΠΎΠ²), ΠΈ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ mutex. ΠŸΡ€ΠΈ использовании scoped_lock, Ссли выбрасываСтся ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΈΠ»ΠΈ функция Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅, ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ scoped_lock автоматичСски уничтоТаСтся ΠΈ mutex разблокируСтся.

ИспользованиС ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠ° позволяСт ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ всю Ρ€Π°Π±ΠΎΡ‚Ρƒ, ΠΎΠ΄Π½Π°ΠΊΠΎ хочСтся Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ большСго. ΠŸΡ€ΠΈ Ρ‚Π°ΠΊΠΎΠΌ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π΅ Π½Π΅Ρ‚ различия ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ΠΌ ΠΈ записью, Ρ‡Ρ‚ΠΎ сущСствСнно, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ нСэффСктивно Π·Π°ΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ ΠΏΠΎΡ‚ΠΎΠΊΠΈ ΠΆΠ΄Π°Ρ‚ΡŒ Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ доступа ΠΊ рСсурсу, ΠΊΠΎΠ³Π΄Π° ΠΌΠ½ΠΎΠ³ΠΈΠ΅ ΠΈΠ· Π½ΠΈΡ… Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ чтСния, для ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π½Π΅ трСбуСтся ΠΌΠΎΠ½ΠΎΠΏΠΎΠ»ΡŒΠ½Ρ‹ΠΉ доступ. Для этого Π² Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅ Boost Threads прСдусмотрСн класс read_write_mutex. ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 12.3 ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ 12.2, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ read_write_mutex с Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ-Ρ‡Π»Π΅Π½ΠΎΠΌ front, которая позволяСт Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰Π΅ΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ копию ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ элСмСнта ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ Π±Π΅Π· Π΅Π³ΠΎ выталкивания.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 12.3. ИспользованиС ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠ° чтСния/записи

#include <iostream>

#include <boost/thread/thread.hpp>

#include <boost/thread/read_write_mutex.hpp>

#include <string>


template<typename T>

class Queue {

 public:

 Queue() : // Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ чтСния/записи ΠΈ ΠΏΡ€ΠΈΠ΄Π°Ρ‚ΡŒ Π΅ΠΌΡƒ ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚

           // записи

 rwMutex_(boost::read_write_scheduling_policy::writer_priority) {}

 ~Queue() {}

 void enqueue(const T& x) {

  // Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ чтСния/записи, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ enqueue

  // обновляСт состояниС

  boost::read_write_mutex::scoped_write_lock writeLock(rwMutex_);

  list_.push_back(x);

 }


 T dequeue() {

  // Π‘Π½ΠΎΠ²Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ для записи

  boost::read_write_mutex::scoped_write_lock writeLock(rwMutex_);

  if (list_.empty())

   throw "empty!";

  T tmp = list_.front();

  list_.pop_front();

  return(tmp);

 }


 T getFront() {

  // Π­Ρ‚ΠΎ опСрация чтСния, поэтому трСбуСтся Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для чтСния

  boost::read_write_mutex::scoped_read_lock.readLock(rwMutex_);

  if (list_.empty())

   throw "empty!";

  return(list_.front());

 }

private:

 std::list<T> list_;

 boost::read_write_mutex rwMutex_;

};


Queue<std::string> queueOfStrings;


void sendSomething() {

 std::string s;

 for (int i = 0, i < 10; ++i) {

  queueOfStrings.enqueue("Cyrus");

 }

}


void checkTheFront() {

 std::string s;

 for (int i=0; i < 10; ++i) {

  try {

   s = queueOfStrings.getFront();

  } catch(...) {}

 }

}


int main() {

 boost::thread thr1(sendSomething);

 boost::thread_group grp;