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

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

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

T dequeueIfEquals(const T& t) {

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

 if (list_.front() == t)

 // ...

Π‘ΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ состояния состязания Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°, Π½ΠΎ этот ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π΄Π°Ρ‚ΡŒ ΠΎΠ±Ρ‰Π΅Π΅ прСдставлСниС ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Π΅Π³ΠΎ слСдуСт ΠΎΡΡ‚Π΅Ρ€Π΅Π³Π°Ρ‚ΡŒΡΡ. По ΠΌΠ΅Ρ€Π΅ увСличСния количСства ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΈ совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Ρ… рСсурсов состояния состязания ΠΎΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ Π±ΠΎΠ»Π΅Π΅ ΠΈΠ·ΠΎΡ‰Ρ€Π΅Π½Π½Ρ‹ΠΌΠΈ ΠΈ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΠ²Π°Ρ‚ΡŒ ΠΈΡ… слоТнСС. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ слСдуСт Π±Ρ‹Ρ‚ΡŒ особСнно остороТным Π½Π° этапС проСктирования, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π΅ Π΄ΠΎΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ ΠΈΡ….

Π’ ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ самоС слоТноС β€” Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ сСриализованный доступ ΠΊ рСсурсам, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Ссли это сдСлано Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ, ΠΎΡ‚Π»Π°Π΄ΠΊΠ° становится ΠΊΠΎΡˆΠΌΠ°Ρ€ΠΎΠΌ. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ многопоточная ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΏΠΎ своСй сути Π½Π΅Π΄Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π° (Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΏΠΎΡ‚ΠΎΠΊΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ Π² Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΎΠΉ очСрСдности ΠΈ с Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌΠΈ ΠΊΠ²Π°Π½Ρ‚Π°ΠΌΠΈ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ Π½ΠΎΠ²ΠΎΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹), ΠΎΡ‡Π΅Π½ΡŒ Ρ‚Ρ€ΡƒΠ΄Π½ΠΎ Ρ‚ΠΎΡ‡Π½ΠΎ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΡ‚ΡŒ мСсто ΠΈ способ ΠΎΡˆΠΈΠ±ΠΎΡ‡Π½ΠΎΠΉ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Ρ‡Π΅Π³ΠΎ-Π»ΠΈΠ±ΠΎ. Π—Π΄Π΅ΡΡŒ Π΅Ρ‰Π΅ Π² большСй стСпСни, Ρ‡Π΅ΠΌ Π² ΠΎΠ΄Π½ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ, Π½Π°Π΄Π΅ΠΆΠ½Ρ‹ΠΉ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ позволяСт ΠΌΠΈΠ½ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π·Π°Ρ‚Ρ€Π°Ρ‚Ρ‹ Π½Π° ΠΎΡ‚Π»Π°Π΄ΠΊΡƒ ΠΈ ΠΏΠ΅Ρ€Π΅Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ.

12.3. Π£Π²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ° Π΄Ρ€ΡƒΠ³ΠΈΠΌ

ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ°

Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ шаблон, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΎΠ΄ΠΈΠ½ ΠΏΠΎΡ‚ΠΎΠΊ (ΠΈΠ»ΠΈ Π³Ρ€ΡƒΠΏΠΏΠ° ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²) выполняСт ΠΊΠ°ΠΊΠΈΠ΅-Ρ‚ΠΎ дСйствия, ΠΈ трСбуСтся ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ± этом ΡƒΠ·Π½Π°Π» Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊ (ΠΈΠ»ΠΈ Π³Ρ€ΡƒΠΏΠΏΠ° ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²). ΠœΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π³Π»Π°Π²Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΏΠΎΠ΄Ρ‡ΠΈΠ½Π΅Π½Π½Ρ‹ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌ, ΠΈΠ»ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΎΠ΄Π½Π° Π³Ρ€ΡƒΠΏΠΏΠ° ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² для пополнСния ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ ΠΈ другая для удалСния Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ· ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ ΠΈ выполнСния Ρ‡Π΅Π³ΠΎ-Π»ΠΈΠ±ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠ³ΠΎ.

РСшСниС

Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ mutex ΠΈ condition, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Ρ‹ Π² boost/thread/mutex.hpp ΠΈ boost/thread/condition.hpp. МоТно ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ условиС (condition) для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ ситуации ΠΈ ΠΏΡ€ΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΠΈ Ρ‚Π°ΠΊΠΎΠΉ ситуации ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»ΡΡ‚ΡŒ всС Π΅Π΅ ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠΈ. ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 12.4 ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Ρƒ ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠΉ Π² ΠΌΠΎΠ΄Π΅Π»ΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Β«Π³Π»Π°Π²Π½Ρ‹ΠΉ/ΠΏΠΎΠ΄Ρ‡ΠΈΠ½Π΅Π½Π½Ρ‹Π΅Β».

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 12.4. ΠŸΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠΉ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ

#include <iostream>

#include <boost/thread/thread.hpp>

#include <boost/thread/condition.hpp>

#include <boost/thread/mutex.hpp>

#include <list>

#include <string>


class Request { /*...*/ };


// ΠŸΡ€ΠΎΡΡ‚ΠΎΠΉ класс ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ Π·Π°Π΄Π°Π½ΠΈΠΉ; Π² Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ вмСсто этого класса

// ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ std::queue

template<typename T>

class JobQueue {

public:

 JobQueue() {}

 ~JobQueue() {}


 void submitJob(const T& x) {

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

  list_.push_back(x);

  workToBeDone_.notify_one();

 }


 T getJob() {

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

  workToBeDone_.wait(lock); // Π–Π΄Π°Ρ‚ΡŒ удовлСтворСния этого условия, Π·Π°Ρ‚Π΅ΠΌ

                            // Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ

  T tmp = list_.front();

  list_.pop_front();

  return(tmp);

 }


private:

 std::list<T> list_;

 boost::mutex mutex_;

 boost::condition workToBeDone_;

};


JobQueue<Request> myJobQueue;


void boss() {

 for (;;) {

  // ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΡ‚ΠΊΡƒΠ΄Π°-Ρ‚ΠΎ запрос

  Request req;

  myJobQueue.submitJob(req);

 }

}


void worker() {

 for (;;) {

  Request r(myJobQueue.getJob());

  // Π’Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΊΠ°ΠΊΠΈΠ΅-Ρ‚ΠΎ дСйствия с Π·Π°Π΄Π°Π½ΠΈΠ΅ΠΌ...

 }

}


int main() {

 boost::thread thr1(boss);

 boost::thread thr2(worker);

 boost::thread thr3(worker);

 thr1.join();

 thr2.join();

 thr3.join();

}

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

ΠžΠ±ΡŠΠ΅ΠΊΡ‚ условия ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ mutex ΠΈ позволяСт Π΄ΠΎΠΆΠ΄Π°Ρ‚ΡŒΡΡ ситуации, ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ становится Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ. Рассмотрим ΠΏΡ€ΠΈΠΌΠ΅Ρ€ 12.4, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ прСдставлСна модифицированная вСрсии класса Queue ΠΈΠ· ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° 12.2. Π― ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π» ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ Queue, получая Π±ΠΎΠ»Π΅Π΅ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΡƒΡŽ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ, Π° ΠΈΠΌΠ΅Π½Π½ΠΎ JobQueue, ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΡΠ²Π»ΡΡŽΡ‚ΡΡ заданиями, ΠΏΠΎΡΡ‚ΡƒΠΏΠ°ΡŽΡ‰ΠΈΠΌΠΈ Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ со стороны Π³Π»Π°Π²Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ° ΠΈ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌΡ‹ΠΌΠΈ ΠΏΠΎΠ΄Ρ‡ΠΈΠ½Π΅Π½Π½Ρ‹ΠΌΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ.

Π‘Π°ΠΌΠΎΠ΅ Π²Π°ΠΆΠ½ΠΎΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ класса JobQueue связано ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ-Ρ‡Π»Π΅Π½ΠΎΠΌ workToBeDone_ Ρ‚ΠΈΠΏΠ° condition. Π­Ρ‚Π° пСрСмСнная ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, имССтся ΠΈΠ»ΠΈ Π½Π΅Ρ‚ Π·Π°Π΄Π°Π½ΠΈΠ΅ Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ. Когда ΠΏΠΎΡ‚ΠΎΠΊΡƒ трСбуСтся ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ элСмСнт ΠΈΠ· ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ, ΠΎΠ½ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ getJob, которая пытаСтся Π·Π°Ρ…Π²Π°Ρ‚ΠΈΡ‚ΡŒ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ ΠΈ Π·Π°Ρ‚Π΅ΠΌ Π΄ΠΎΠΆΠΈΠ΄Π°Ρ‚ΡŒΡΡ возникновСния Π½ΠΎΠ²ΠΎΠΉ ситуации, Ρ‡Ρ‚ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ строки.

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

workToBeDone_.wait(lock);

ΠŸΠ΅Ρ€Π²Π°Ρ строка Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ. Вторая строка Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ ΠΈ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΈΡ‚ Π΅Π³ΠΎ Π² состояниС оТидания ΠΈΠ»ΠΈ Π² Π½Π΅Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΠ΅ состояниС Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΡƒΠ΄ΠΎΠ²Π»Π΅Ρ‚Π²ΠΎΡ€Π΅Π½ΠΎ условиС. Π Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠ° позволяСт Π΄Ρ€ΡƒΠ³ΠΈΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ этот ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ; ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Π½ΠΈΡ… Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΠΎΠ΅ условиС, Π² ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠΈ Π½Π΅ смогут Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ, ΠΏΠΎΠΊΠ° ΠΎΠ΄ΠΈΠ½ ΠΏΠΎΡ‚ΠΎΠΊ ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚ возникновСния Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΠ³ΠΎ условия.

Π’ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ submitJob послС помСщСния задания Π²ΠΎ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠΉ список я Π΄ΠΎΠ±Π°Π²ΠΈΠ» ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ строку.

workToBeDone_.notify_one();

Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ «удовлСтворяСтся» условиС, Π² ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠΈ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ находится getJob. Π€ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ это ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Ссли ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ ΠΊΠ°ΠΊΠΈΠ΅-Π½ΠΈΠ±ΡƒΠ΄ΡŒ ΠΏΠΎΡ‚ΠΎΠΊΠΈ, Π²Ρ‹Π·Π²Π°Π²ΡˆΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ wait для этого условия, Ρ‚ΠΎ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Π½ΠΈΡ… ΠΏΠ΅Ρ€Π΅ΠΉΠ΄Π΅Ρ‚ Π² состояниС выполнСния. Для Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ getJob это ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ΠΈΠ΅ Ρ€Π°Π±ΠΎΡ‚Ρ‹, приостановлСнной Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ строкС:

workToBeDone_.wait(lock);

Но это Π΅Ρ‰Π΅ Π½Π΅ всС. Ѐункция wait Π΄Π΅Π»Π°Π΅Ρ‚ Π΄Π²Π΅ Π²Π΅Ρ‰ΠΈ: ΠΎΠ½Π° доТидаСтся Π²Ρ‹Π·ΠΎΠ²Π° Π² ΠΊΠ°ΠΊΠΎΠΌ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ ΠΏΠΎΡ‚ΠΎΠΊΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ notify_one ΠΈΠ»ΠΈ notify_all для Π΄Π°Π½Π½ΠΎΠ³ΠΎ условия, Π·Π°Ρ‚Π΅ΠΌ ΠΎΠ½Π° пытаСтся Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ, ΠΊΠΎΠ³Π΄Π° submitJob Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ notify_all, фактичСски происходит ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅: ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰ΠΈΠΉ ΠΏΠΎΡ‚ΠΎΠΊ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ Π² состояниС выполнСния ΠΈ Π½Π° ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ шагС пытаСтся Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ всС Π΅Ρ‰Π΅ Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ функция submitJob, поэтому ΠΎΠ½ вновь ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ Π² состояниС оТидания, ΠΏΠΎΠΊΠ° Π½Π΅ Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ функция submitJob. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, condition::wait Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ Π±Ρ‹Π» Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ ΠΏΡ€ΠΈ Π΅Π³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π΅, ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ оказываСтся Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ ΠΈ Π·Π°Ρ‚Π΅ΠΌ вновь Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ ΠΏΡ€ΠΈ ΡƒΠ΄ΠΎΠ²Π»Π΅Ρ‚Π²ΠΎΡ€Π΅Π½ΠΈΠΈ условия.

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

ΠŸΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ условия позволяСт ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ ситуациСй Π±ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΠ½ΠΊΠΎ, Ρ‡Π΅ΠΌ ΠΏΡ€ΠΈ использовании ΠΎΠ΄Π½ΠΈΡ… Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠΎΠ² ΠΈ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΠΊ. Рассмотрим прСдставлСнный Ρ€Π°Π½Π΅Π΅ класс Queue. ΠŸΠΎΡ‚ΠΎΠΊΠΈ, ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰ΠΈΠ΅ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ элСмСнта ΠΈΠ· ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ, находятся Π² состоянии оТидания Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° ΠΎΠ½ΠΈ Π½Π΅ смогут ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ для записи ΠΈ Π·Π°Ρ‚Π΅ΠΌ ΠΈΠ·Π²Π»Π΅Ρ‡ΡŒ элСмСнт ΠΈΠ· ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ. ΠœΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ это Π±ΡƒΠ΄Π΅Ρ‚ Ρ…ΠΎΡ€ΠΎΡˆΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π±Π΅Π· примСнСния ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Π»ΠΈΠ±ΠΎ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° сигнализации, Π½ΠΎ Ρ‚Π°ΠΊ Π»ΠΈ Π½Π° самом Π΄Π΅Π»Π΅? А Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ‚, ΠΊΠΎΠ³Π΄Π° ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ окаТСтся пустой? Π£ вас Π½Π΅Ρ‚ большого Π²Ρ‹Π±ΠΎΡ€Π° ΠΏΡ€ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ dequeue, Ссли Π²Ρ‹ ΠΆΠ΄Π΅Ρ‚Π΅ удовлСтворСния Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ условия: ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° наличия элСмСнтов Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ ΠΈ, Ссли ΠΎΠ½ΠΈ ΠΎΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‚, Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ управлСния; использованиС Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠ°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ блокируСтся ΠΏΡ€ΠΈ пустой ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ ΠΈ разблокируСтся, ΠΊΠΎΠ³Π΄Π° ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ содСрТит Π΄Π°Π½Π½Ρ‹Π΅ (Π½Π΅ подходящСС Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅) ΠΈΠ»ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ значСния, ΠΊΠΎΠ³Π΄Π° ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ оказываСтся пустой. ВсС это ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°Ρ‚ΠΈΡ‡Π½ΠΎ ΠΈΠ»ΠΈ нСэффСктивно. Если Π²Ρ‹ просто Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚Π΅ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅, ΠΊΠΎΠ³Π΄Π° ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ пустая, выбрасывая ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΈΠ»ΠΈ возвращая ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Ρ‚ΠΎ вашим ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌ придСтся постоянно ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ ΠΏΠΎΡΡ‚ΡƒΠΏΠ°ΡŽΡ‰ΠΈΠ΅ значСния. Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ Π±Π΅ΡΠΏΠΎΠ»Π΅Π·Π½ΡƒΡŽ Ρ‚Ρ€Π°Ρ‚Ρƒ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ.

ΠžΠ±ΡŠΠ΅ΠΊΡ‚ condition позволяСт ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌ Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒΡΡ Π² Π½Π΅Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΠΌ состоянии, поэтому процСссор ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π΄Ρ€ΡƒΠ³ΠΎΠ΅, ΠΊΠΎΠ³Π΄Π° условиС Π½Π΅ удовлСтворяСтся. ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΠΌ Π²Π΅Π±-сСрвСр, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠΉ ΠΏΡƒΠ» Ρ€Π°Π±ΠΎΡ‡ΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‰ΠΈΡ… ΠΏΠΎΡΡ‚ΡƒΠΏΠ°ΡŽΡ‰ΠΈΠ΅ запросы. Π—Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π»ΡƒΡ‡ΡˆΠ΅ ΠΈΠΌΠ΅Ρ‚ΡŒ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠΈ, находящиСся Π² состоянии оТидания, ΠΊΠΎΠ³Π΄Π° Π½Π΅Ρ‚ Π½ΠΈΠΊΠ°ΠΊΠΎΠΉ активности, Ρ‡Π΅ΠΌ Π·Π°ΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ ΠΈΡ… Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ бСсконСчный Ρ†ΠΈΠΊΠ» ΠΈΠ»ΠΈ Β«Π·Π°ΡΡ‹ΠΏΠ°Ρ‚ΡŒΒ» ΠΈ Β«ΠΏΡ€ΠΎΡΡ‹ΠΏΠ°Ρ‚ΡŒΡΡΒ» пСриодичСски для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ.

12.4. ΠžΠ΄Π½ΠΎΠΊΡ€Π°Ρ‚Π½Π°Ρ инициализация совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Ρ… рСсурсов

ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ°

Π˜ΠΌΠ΅Π΅Ρ‚ΡΡ нСсколько ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΡ… ΠΎΠ΄ΠΈΠ½ рСсурс, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π·.

РСшСниС

Π›ΠΈΠ±ΠΎ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠΉΡ‚Π΅ этот рСсурс Π΄ΠΎ запуска ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², Π»ΠΈΠ±ΠΎ, Ссли ΠΏΠ΅Ρ€Π²ΠΎΠ΅ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ call_once, ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΡƒΡŽ Π² <boost/thread/once.hpp>, ΠΈ Ρ‚ΠΈΠΏ once_flag. ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 12.5 ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ call_once.