992 Chapter 18: ConcurrencyTo synchronize the output in a way that eac การแปล - 992 Chapter 18: ConcurrencyTo synchronize the output in a way that eac ไทย วิธีการพูด

992 Chapter 18: ConcurrencyTo synch

992 Chapter 18: Concurrency
To synchronize the output in a way that each call of print() exclusively writes its characters, we
introduce a mutex for the print operation and a lock guard, which locks the corresponding protected
section:
std::mutex printMutex; // enable synchronized output with print()
...
void print (const std::string& s)
{
std::lock_guard l(printMutex);
...
}
Now the output is simply something like this:
Hello from a first thread
Hello from the main thread
Hello from a second thread
This output also is possible (but not guaranteed) when no lock is used.
Here, the lock() of the mutex, called by the constructor of the lock guard, blocks if the resource
is acquired already. It blocks until access to the protected section is available again. However, the
order of locks is still undefined. Thus, the three outputs might still be written in arbitrary order.
Recursive Locks
Sometimes, the ability to lock recursively is required. Typical examples are active objects or monitors,
which contain a mutex and take a lock inside every public method to protect data races corrupting
the internal state of the object. For example, a database interface might look as follows:
class DatabaseAccess
{
private:
std::mutex dbMutex;
... // state of database access
public:
void createTable (...)
{
std::lock_guard lg(dbMutex);
...
}
void insertData (...)
{
std::lock_guard lg(dbMutex);
...
}
...
};
www.it-ebooks.info
18.5 Mutexes and Locks 993
When we introduce a public member function that might call other public member functions, this
can become complicated:
void createTableAndInsertData (...)
{
std::lock_guard lg(dbMutex);
...
createTable(...); // ERROR: deadlock because dbMutex is locked again
}
Calling createTableAndInsertData() will result in a deadlock because after locking dbMutex,
the call of createTable() will try to lock dbMutex again, which will block until the lock of
dbMutex is available, which will never happen because createTableAndInsertData() will block
until createTable() is done.
The C++ standard library permits the second attempt to throw a std::system_error (see Section
4.3.1, page 43) with the error code resource_deadlock_would_occur (see Section 4.3.2,
page 45) if the platform detects such a deadlock. But this is not required and is often not the case.
By using a recursive_mutex, this behavior is no problem. This mutex allows multiple locks
by the same thread and releases the lock when the last corresponding unlock() call is called:
class DatabaseAccess
{
private:
std::recursive_mutex dbMutex;
... // state of database access
public:
void insertData (...)
{
std::lock_guard lg(dbMutex);
...
}
void insertData (...)
{
std::lock_guard lg(dbMutex);
...
}
void createTableAndinsertData (...)
{
std::lock_guard lg(dbMutex);
...
createTable(...); // OK: no deadlock
}
...
};
www.it-ebooks.info
994 Chapter 18: Concurrency
Tried and Timed Locks
Sometimes a program wants to acquire a lock but doesn’t want to block (forever) if this is not
possible. For this situation, mutexes provide a try_lock() member function that tries to acquire a
lock. If it succeeds, it returns true; if not, false.
To still be able to use a lock_guard so that any exit from the current scope unlocks the mutex,
you can pass an additional argument adopt_lock to its constructor:
std::mutex m;
// try to acquire a lock and do other stuff while this isn’t possible
while (m.try_lock() == false) {
doSomeOtherStuff();
}
std::lock_guard lg(m,std::adopt_lock);
...
Note that try_lock() might fail spuriously. That is, it might fail (return false) even if the lock is
not taken.20
To wait only for a particular amount of time, you can use a timed mutex. The special mutex
classes std::timed_mutex and std::recursive_timed_mutex additionally allow calling
try_lock_for() or try_lock_until() to wait for at most a specified duration of time or until a
specified point in time has arrived. This, for example, might help if you have real-time requirements
or want to avoid possible deadlock situations. For example:
std::timed_mutex m;
// try for one second to acquire a lock
if (m.try_lock_for(std::chrono::seconds(1))) {
std::lock_guard lg(m,std::adopt_lock);
...
}
else {
couldNotGetTheLock();
}
Note that try_lock_for() and try_lock_until() usually will differ when dealing with systemtime
adjustments (see Section 5.7.5, page 160, for details).
Dealing with Multiple Locks
Usually a thread should lock only one mutex at a time. However, it is sometimes necessary to lock
more than one mutex (for example, to transfer data from one protected resource to another). In that
20 This behavior is provided for memory-ordering reasons but is not widely known. Thanks to Hans Boehm and
Bartosz Milewski for pointing it out.
www.it-ebooks.info
18.5 Mutexes and Locks 995
case, dealing with the lock mechanisms introduced so far can become complicated and risky: You
might get the first but not the second lock, or deadlock situations may occur if you lock the same
locks in a different order.
The C++ standard library, therefore, provides convenience functions to try to lock multiple mutexes.
For example:
std::mutex m1;
std::mutex m2;
...
{
std::lock (m1, m2); // lock both mutexes (or none if not possible)
std::lock_guard lockM1(m1,std::adopt_lock);
std::lock_guard lockM2(m2,std::adopt_lock);
...
} // automatically unlock all mutexes
The global std::lock() locks all mutexes passed as arguments, blocking until all mutexes are
locked or until an exception is thrown. In the latter case, it unlocks mutexes already successfully
locked. As usual, after successful locking, you can and should use a lock guard initialized with
adopt_lock as second argument to ensure that, in any case, the mutexes are unlocked when leaving
the scope. Note that this lock() provides a deadlock-avoidance mechanism, which, however, means
that the order of locking inside a multiple lock is undefined.
In the same way, you can try to acquire multiple locks without blocking if not all locks are
available. The global std::try_lock() returns -1 if all locks were possible. If not, the return
value is the zero-based index of the first failed lock. In that case, all succeeded locks are unlocked
again. For example:
std::mutex m1;
std::mutex m2;
int idx = std::try_lock (m1, m2); // try to lock both mutexes
if (idx < 0) { // both locks succeeded
std::lock_guard lockM1(m1,std::adopt_lock);
std::lock_guard lockM2(m2,std::adopt_lock);
...
} // automatically unlock all mutexes
else {
// idx has zero-based index of first failed lock
std::cerr
0/5000
จาก: -
เป็น: -
ผลลัพธ์ (ไทย) 1: [สำเนา]
คัดลอก!
992 บท 18: เกิด
ให้แสดงผลในแบบที่ว่า แต่ละโทร print() ขอนำเสนอเขียนเป็นอักขระ เรา
แนะนำ mutex ยามล็อค ที่ล็อคให้สอดคล้องกับป้องกันและการพิมพ์
ส่วน:
std::mutex printMutex / / เปิดใช้งานการแสดงผลให้ตรงกัน ด้วย(พิมพ์)
...
ยกเลิกพิมพ์ (ค่า const std::string& s)
{
std::lock_guard l(printMutex);
...
}
ขณะนี้ผลผลิตเป็นเพียงเหมือน:
สวัสดีจากเธรดแรก
สวัสดีจากเธรดหลัก
สวัสดีจากเธรดที่สอง
ผลลัพธ์นี้จะเป็นไปได้ (แต่ไม่รับประกัน) เมื่อใช้ล็อคไม่
นี่ lock() ของ mutex เรียก โดยตัวสร้างของยามล็อค บล็อกถ้าทรัพยากร
ซื้อมาแล้ว มันบล็อกจนถึงส่วนได้รับการป้องกันได้อีก อย่างไรก็ตาม การ
สั่งของล็อคยังไม่ได้ จึง แสดงผล 3 อาจยังเขียนในอำเภอใจสั่ง
ล็อคซ้ำ
บางครั้ง ความสามารถในการล็อค recursively จำเป็นได้ ตัวอย่างทั่วไปคือ วัตถุหรือจอ,
ซึ่งประกอบด้วย mutex และใช้ล็อคภายในทุกวิธีที่สาธารณะเพื่อป้องกันข้อมูลแข่งขันทำลาย
สถานะภายในของวัตถุ ตัวอย่าง อินเทอร์เฟซฐานข้อมูลอาจดูเป็นดังนี้:
คลา DatabaseAccess
{
ส่วนตัว:
std::mutex dbMutex;
... / / สถานะของฐานข้อมูล access
สาธารณะ:
createTable โมฆะ (...)
{
std::lock_guard lg (dbMutex);
...
}
โมฆะ insertData (...)
{
std::lock_guard lg(dbMutex);
...
}
...
};
www.it-ebooks.info
18.5 Mutexes และล็อค 993
เมื่อเราแนะนำฟังก์ชันสมาชิกสาธารณะที่อาจเรียกสมาชิกสาธารณะอื่น ๆ ฟังก์ชัน นี้
สามารถกลายเป็นซับซ้อน:
createTableAndInsertData ยกเลิก (...)
{
std::lock_guard lg(dbMutex);
...
createTable(...); / / ข้อผิดพลาด: deadlock เนื่องจาก dbMutex ถูกล็อกอีก
}
createTableAndInsertData() โทรศัพท์จะทำให้เกิดการล็อกตายเนื่องจากหลังล็อค dbMutex,
เรียก createTable() จะพยายามล็อก dbMutex อีก ซึ่งจะบล็อกจนล็อคของ
dbMutex มี ซึ่งจะไม่เกิดขึ้นเนื่องจาก createTableAndInsertData() จะบล็อก
จนทำ createTable().
C เดอะไลบรารีมาตรฐานอนุญาตให้สองพยายามโยนเป็น std::system_error (ดูส่วน
4.3.1 หน้า 43) ด้วย resource_deadlock_would_occur รหัสข้อผิดพลาด (ดู 4.3.2,
หน้า 45) ถ้าปิดตายดังกล่าวตรวจพบแพลตฟอร์ม แต่นี้ไม่จำเป็น และมักจะไม่ได้กรณี
โดยใช้การ recursive_mutex ซึ่งเป็นปัญหาไม่ Mutex นี้อนุญาตให้ล็อคหลาย
โดยเธรดเดียวกัน และปลดล็อคเมื่อเรียกโทร unlock() ที่สอดคล้องกันครั้งล่าสุด:
คลา DatabaseAccess
{
ส่วนตัว:
std::recursive_mutex dbMutex;
... / / สถานะของฐานข้อมูล access
สาธารณะ:
ยกเลิก insertData (...)
{
std::lock_guard lg (dbMutex);
...
}
โมฆะ insertData (...)
{
std::lock_guard lg (dbMutex);
...
}
โมฆะ createTableAndinsertData (...)
{
std::lock_guard lg(dbMutex);
...
createTable(...); / / ตกลง: การชะงักงันไม่
}
...
};
www.it-ebooks.info
994 บท 18: เกิด
Tried และเวลาล็อค
บางโปรแกรมต้องการบล็อค แต่ไม่ต้องการบล็อค (ตลอดไป) ถ้าไม่
ได้ สถานการณ์นี้ mutexes มีฟังก์ชันสมาชิก try_lock() ที่พยายามซื้อตัว
ล็อค ถ้ามันสำเร็จ กลับเป็นจริง ถ้าไม่ ไม่
ยัง สามารถใช้ lock_guard การให้ใด ๆ ออกจากขอบเขตปัจจุบันปลดล็อค mutex,
คุณสามารถผ่าน adopt_lock อาร์กิวเมนต์เพิ่มเติมเป็นตัวสร้างความ:
std::mutex m;
/ / ลองการบล็อค และทำสิ่งอื่น ๆ ในขณะนี้ไม่ได้
ขณะ (m.try_lock() ==เท็จ) {
doSomeOtherStuff ();
}
std::lock_guard lg (m, std::adopt_lock);
...
หมายเหตุ try_lock() ที่อาจล้มเหลว spuriously กล่าวคือ มันอาจล้มเหลว (ส่งคืนเท็จ) แม้จะล็อค
ไม่ taken.20
ต้องรอสำหรับจำนวนเฉพาะเวลาเท่านั้น คุณสามารถใช้ mutex เวลา Mutex พิเศษ
เรียน std::timed_mutex และ std::recursive_timed_mutex นอกจากนี้อนุญาตให้ calling
try_lock_for() หรือ try_lock_until() เพื่อรอมากที่สุดระยะเวลา หรือจนกว่าการ
ระบุจุดในเวลาที่มาถึง นี้ เช่น อาจช่วยถ้าคุณมีความต้องการจริง
หรือต้องการหลีกเลี่ยงสถานการณ์การชะงักงันได้ ตัวอย่าง:
std::timed_mutex m;
/ / ลองในหนึ่งวินาทีรับล็อค
ถ้า (m.try_lock_for (std::chrono::seconds(1))) {
std::lock_guard lg (m, std::adopt_lock);
...
}
อื่น {
couldNotGetTheLock ();
}
หมายเหตุว่า try_lock_for() และ try_lock_until() มักจะแตกต่างกันเมื่อจัดการกับ systemtime
(ดูส่วน 5.7.5 หน้า 160 ปรับปรุง สำหรับรายละเอียด) .
กับล็อคหลาย
มักเธรดควรล็อคเดียว mutex ครั้ง อย่างไรก็ตาม บางครั้งจำเป็นต้องล็อค
mutex มากกว่าหนึ่ง (ตัวอย่าง การโอนย้ายข้อมูลจากทรัพยากรได้รับการป้องกันหนึ่งไปยังอีก) ใน
20 ลักษณะนี้ให้จำลำดับเหตุผล แต่จะไม่รู้จักกันอย่างกว้างขวาง ด้วยระบบ Boehm ฮันส์ และ
Bartosz Milewski สำหรับชี้ออก.
wwwMutexes มัน ebooks.info
18.5 และล็อค 995
กรณี การจัดการกับกลไกล็อคแนะนำจนสามารถทำงานได้ซับซ้อน และมีความเสี่ยง: คุณ
อาจจะครั้งแรก แต่ไม่ล็อคที่สอง การสถานการณ์การชะงักงันอาจเกิดขึ้นหากคุณล็อกเดียวกัน
ล็อคในแบบต่าง ๆ สั่ง
C เดอะไลบรารีมาตรฐาน ดังนั้น มีฟังก์ชันสะดวกพยายามล็อคหลาย mutexes การ
ตัวอย่าง:
std::mutex m1;
มาตรฐาน::mutex m2;
...
{
std::lock (m1, m2); / / ล็อคทั้ง mutexes (หรือไม่ถ้าไม่ได้)
std::lock_guard lockM1(m1,std::adopt_lock);
std::lock_guard lockM2(m2,std::adopt_lock);
...
} / / ปลดล็อกโดยอัตโนมัติทั้งหมด mutexes
std::lock() สากลล็อก mutexes ทั้งหมดที่ส่งผ่านเป็นอาร์กิวเมนต์ บล็อกจนกว่าจะหมด mutexes
ขว้างถูกล็อก หรือจนกว่า จะมีข้อยกเว้น ในกรณีหลัง มันปลดล็อค mutexes แล้วเรียบร้อย
ล็อค ตามปกติ หลังล็อคประสบความสำเร็จ คุณสามารถ และควรใช้ยามล็อคที่เริ่มต้นด้วย
adopt_lock เป็นอาร์กิวเมนต์ที่สองเพื่อให้แน่ใจว่า,, mutexes ที่จะปลดล็อคเมื่อออกจาก
ขอบเขต ทราบว่า lock() นี้ช่วยให้กลไกการหลีกเลี่ยงการชะงักงัน ซึ่ง อย่างไรก็ตาม
ว่าลำดับของล็อกภายในล็อคหลายไม่
เดียว คุณสามารถพยายามซื้อล็อคหลาย โดยบล็อกถ้า ไม่ล็อคทั้งหมด
ว่าง Std::try_lock() สากลคืนค่า -1 ถ้าล็อคทั้งหมดได้ ถ้าส่งคืนไม่
ค่าดัชนี zero-based ของล็อคล้มเหลวครั้งแรกคือ ในกรณี ล็อคทั้งหมด succeeded จะปลดล็อก
อีก ตัวอย่าง:
std::mutex m1;
std::mutex m2;
int idx = std::try_lock (m1, m2); / / พยายามล็อกทั้งสอง mutexes
ถ้า (idx < 0) { / / ล็อคทั้งสองสำเร็จ
std::lock_guard lockM1(m1,std::adopt_lock);
std::lock_guard lockM2(m2,std::adopt_lock);
...
} / / ปลดล็อกโดยอัตโนมัติทั้งหมด mutexes
อื่น {
/ idx มีดัชนี zero-based ของล็อคแรกล้มเหลว
std::cerr << "อาจไม่ล็อก mutex m" << idx 1 << std::endl;
}
ทราบว่า try_lock() นี้มีกลไกล็อกตายหลีกเลี่ยงไม่ แทน รับประกัน
ล็อคจะพยายามกับการส่งผ่านอาร์กิวเมนต์ด้วย
ทราบยังว่า โทร lock() หรือ try_lock() โดยใช้ล็อค โดยรักษาความเป็นปกติ
ไม่ว่าความ ถึงแม้ว่ารหัสดูเหมือนสร้างล็อคที่นำออกใช้โดยอัตโนมัติ
เมื่อออกจากขอบเขต นี่ไม่ใช่กรณี Mutexes ยังคงถูกล็อก:
www.it-ebooks.info
996 บท 18: เกิด
std::mutex m1;
std::mutex m2;
...
{
std::lock (m1, m2); / / ล็อคทั้ง mutexes (หรือไม่ถ้าไม่ได้)
/ / ไม่ล็อคนำ
...
}
... / / โอ๊ะ: mutexes ล็อค!!!
คลา unique_lock
นอกจากคลาส lock_guard <> ไลบรารีมาตรฐาน C ให้คลา unique_lock <> ซึ่งเป็นการ
มากความยืดหยุ่นมากขึ้นเมื่อทำงานกับล็อคสำหรับ mutexes คลา unique_lock <>ให้เหมือน
อินเทอร์เฟซเป็นคลา lock_guard <> บวกความสามารถในการเขียนโปรแกรมอย่างชัดเจนเมื่อและวิธีการล็อค หรือ
mutex ปลดล็อค จึง วัตถุล็อคนี้อาจ หรืออาจไม่มี mutex ล็อก (หรือที่เรียกว่า เป็นเจ้าของ
mutex) ซึ่งแตกต่างจาก<>lock_guard ซึ่งมีวัตถุที่ล็อกตลอดของ
อายุการใช้งาน21 นอกจากนี้ สำหรับล็อคเฉพาะ คุณสามารถสอบถามว่า mutex ถูกล็อกในขณะนี้โดย
โทร owns_lock() หรือตัวดำเนินการ() bool ได้
ข้อดีหลัก ๆ ของคลาสนี้ยังคือเมื่อ mutex ถูกล็อกในเวลาทำลาย
destructor เรียก unlock() โดยอัตโนมัติก็ได้ ถ้าไม่มี mutex ถูกล็อก destructor ที่ไม่มีอะไร
เมื่อเทียบกับคลา lock_guard unique_lock คลาสมีดังต่อไปนี้เสริม
ตัวสร้าง:
•คุณสามารถผ่าน try_to_lock ในความพยายาม nonblocking ล็อกมี mutex:
std::unique_lock ล็อค (mutex, std::try_to_lock);
...
ถ้า (ล็อค) { / / ถ้าล็อคสำเร็จ
...
}
•คุณสามารถผ่านช่วงเวลาหรือ timepoint ไปที่ตัวสร้างพยายามล็อคสำหรับระยะเวลากำหนด:
std::unique_lock ล็อค (mutex,
std::chrono::seconds(1));
...
•คุณสามารถผ่าน defer_lock เพื่อเริ่มต้นการล็อกโดย mutex (ยัง):
std::unique_lock lock(mutex,std::defer_lock);
...
lock.lock(); / / หรือ (เวลา) (try_lock)
...
21 ล็อคเฉพาะชื่ออธิบายซึ่งลักษณะเช่นนี้มา เช่นเดียวกับตัวชี้เฉพาะ (ดูส่วน 5.2.5,
page 98), คุณสามารถย้ายล็อคระหว่างขอบเขต แต่จะรับประกันได้ว่า ล็อคเดียวเท่านั้นที่เป็นเจ้าของ mutex ที่.
www.it
การแปล กรุณารอสักครู่..
ผลลัพธ์ (ไทย) 2:[สำเนา]
คัดลอก!
992 บทที่ 18: Concurrency
เพื่อประสานการส่งออกในรูปแบบที่แต่ละสายของพิมพ์ () เขียนตัวอักษรเฉพาะของเรา
แนะนำ mutex สำหรับการดำเนินงานการพิมพ์และป้องกันการล็อคซึ่งล็อคได้รับการป้องกันที่สอดคล้อง
ส่วน:
std :: mutex printMutex; / / เปิดออกตรงกับพิมพ์ ()
...
พิมพ์เป็นโมฆะ (const std :: สตริงและ s)
{
std :: lock_guardลิตร (printMutex);
...
}
ขณะนี้การส่งออกเป็นเพียงบางสิ่งบางอย่างเช่นนี้
สวัสดีจากหัวข้อแรก
สวัสดีจากหัวข้อหลัก
สวัสดีจากหัวข้อที่สอง
เอาท์พุทนี้ยังเป็นไปได้ (แต่ไม่รับประกัน) เมื่อล็อคไม่ถูกนำมาใช้
ที่นี่ ล็อค () ของ mutex ที่เรียกว่าโดยการสร้างของยามล็อคบล็อกถ้าทรัพยากร
ที่ได้มาแล้ว บล็อกจนการเข้าถึงส่วนการป้องกันที่มีอยู่อีกครั้ง แต่
คำสั่งของล็อคก็ยังไม่ได้กำหนด ดังนั้นสามผลอาจจะยังคงเป็นลายลักษณ์อักษรในการสั่งซื้อโดยพลการ
ล็อคซ้ำ
บางครั้งความสามารถในการล็อคซ้ำจะต้อง ตัวอย่างทั่วไปเป็นวัตถุที่ใช้งานหรือจอภาพ
ที่มี mutex และใช้ล็อคภายในวิธีการของประชาชนทุกคนที่จะปกป้องเผ่าพันธุ์ข้อมูลเสียหาย
รัฐภายในของวัตถุ ตัวอย่างเช่นการเชื่อมต่อฐานข้อมูลอาจมีลักษณะดังต่อไปนี้
DatabaseAccess ชั้น
{
ส่วนตัว:
std :: mutex dbMutex;
... / / รัฐในการเข้าถึงฐานข้อมูล
สาธารณะ
CreateTable เป็นโมฆะ (... )
{
std :: lock_guardแอลจี (dbMutex);
...
}
เป็นโมฆะ insertData (... )
{
std :: lock_guardแอลจี (dbMutex);
...
}
...
};
www.it-ebooks.info
18.5 mutexes และล็อค 993
เมื่อเราแนะนำฟังก์ชันสมาชิกของประชาชนที่อาจจะเรียกฟังก์ชั่นของสมาชิกที่สาธารณะอื่น ๆ นี้
สามารถกลายเป็นความซับซ้อน:
โมฆะ createTableAndInsertData ( .. )
{
std :: lock_guardแอลจี (dbMutex);
...
CreateTable (... ) / / ข้อผิดพลาด: หยุดชะงักเพราะ dbMutex ถูกล็อคอีกครั้ง
}
โทร createTableAndInsertData () จะส่งผลให้เกิดการหยุดชะงักเพราะหลังจากที่ล็อค dbMutex,
โทรของ CreateTable () จะพยายามที่จะล็อค dbMutex อีกครั้งซึ่งจะป้องกันจนกระทั่งล็อคของ
dbMutex สามารถใช้ได้ซึ่งจะไม่เกิดขึ้นเพราะ createTableAndInsertData () จะป้องกัน
จนกระทั่ง CreateTable () จะทำ
ห้องสมุด C + + มาตรฐานอนุญาตให้พยายามครั้งที่สองที่จะโยน std :: system_error (ดูมาตรา
4.3 .1, หน้า 43) ด้วย resource_deadlock_would_occur รหัสข้อผิดพลาด (ดูมาตรา 4.3.2,
หน้า 45) หากตรวจพบแพลตฟอร์มดังกล่าวหยุดชะงัก แต่นี้ไม่จำเป็นต้องใช้และมักจะไม่ได้กรณีที่
โดยใช้ recursive_mutex พฤติกรรมเช่นนี้จะไม่มีปัญหา mutex นี้จะช่วยให้หลาย ๆ ล็อค
โดยหัวข้อเดียวกันและล็อคออกเมื่อปลดล็อคที่เกี่ยวข้องที่ผ่านมา () โทรเรียกว่า:
DatabaseAccess ชั้น
{
ส่วนตัว:
std :: recursive_mutex dbMutex;
... / / รัฐในการเข้าถึงฐานข้อมูล
สาธารณะ
เป็นโมฆะ insertData ( .. )
{
std :: lock_guardแอลจี (dbMutex);
...
}
เป็นโมฆะ insertData (... )
{
std :: lock_guardแอลจี (dbMutex);
...
}
เป็นโมฆะ createTableAndinsertData (... )
{
std :: lock_guardแอลจี (dbMutex);
...
CreateTable (... ) / / ตกลง: ไม่มีหยุดชะงัก
}
...
};
www.it-ebooks.info
994 บทที่ 18: Concurrency
พยายามและตั้งเวลาล็อค
บางครั้งโปรแกรมที่ต้องการที่จะได้รับ ล็อค แต่ไม่ต้องการที่จะปิดกั้น (ตลอดไป) ถ้านี้ไม่ได้เป็น
ไปได้ สำหรับสถานการณ์นี้ให้ mutexes try_lock () ฟังก์ชันสมาชิกที่พยายามที่จะได้รับ
การล็อค หากประสบความสำเร็จก็จะกลับจริงถ้าไม่เป็นเท็จ
เพื่อให้ยังคงสามารถที่จะใช้ lock_guard เพื่อให้ออกจากขอบเขตปัจจุบันปลดล็อค mutex,
คุณสามารถส่งผ่าน adopt_lock อาร์กิวเมนต์เพิ่มเติมเพื่อสร้างของมัน
std :: mutex ม. ;
/ / พยายามที่จะได้รับการล็อคและทำสิ่งอื่น ๆ ในขณะนี้เป็นไปไม่ได้
ในขณะที่ (m.try_lock () == เท็จ) {
doSomeOtherStuff ();
}
std :: lock_guardแอลจี (ม. , std :: adopt_lock);
...
หมายเหตุ try_lock ที่ () อาจล้มเหลว spuriously นั่นคือมันอาจล้มเหลว (กลับเท็จ) แม้ว่าล็อค
ไม่ taken.20
รอเพียงสำหรับจำนวนเงินที่โดยเฉพาะอย่างยิ่งเวลาที่คุณสามารถใช้ mutex หมดเวลา mutex พิเศษ
เรียน std :: timed_mutex และ std :: recursive_timed_mutex นอกจากนี้ยังช่วยให้การเรียก
try_lock_for () หรือ try_lock_until () เพื่อรอที่มากที่สุดในช่วงระยะเวลาที่กำหนดเวลาหรือจนกว่าจะมี
จุดที่กำหนดในเวลาที่มีมาถึง นี้ตัวอย่างเช่นอาจช่วยถ้าคุณมีความต้องการเวลาจริง
หรือต้องการที่จะหลีกเลี่ยงสถานการณ์ที่หยุดชะงักไปได้ ตัวอย่างเช่น
std :: timed_mutex เมตร
/ / ลองสำหรับคนที่สองที่จะได้รับการล็อค
ถ้า (m.try_lock_for (std :: โครโนกราฟ :: วินาที (1))) {
std :: lock_guardแอลจี (ม. , std :: adopt_lock);
...
}
else {
couldNotGetTheLock ();
}
หมายเหตุ try_lock_for ที่ () และ try_lock_until () มักจะแตกต่างกันเมื่อต้องรับมือกับ SYSTEMTIME
การปรับเปลี่ยน (ดูมาตรา 5.7.5, หน้า 160, สำหรับรายละเอียด )
การจัดการกับระบบล็อคหลาย
ปกติด้ายควรล็อค mutex เพียงหนึ่งในเวลา แต่ก็เป็นบางครั้งจำเป็นต้องล็อค
มากกว่าหนึ่ง mutex (เช่นการถ่ายโอนข้อมูลจากแหล่งข้อมูลที่ได้รับการคุ้มครองอย่างใดอย่างหนึ่งไปยังอีก) ในที่
20 ลักษณะการทำงานนี้มีไว้สำหรับเหตุผลการสั่งซื้อหน่วยความจำ แต่ไม่เป็นที่รู้จักอย่างกว้างขวาง ขอบคุณฮันส์ Boehm และ
Bartosz Milewski สำหรับการชี้ออก
www.it-ebooks.info
18.5 mutexes และล็อค 995
กรณีที่เกี่ยวข้องกับกลไกการล็อคการแนะนำเพื่อให้ห่างไกลสามารถกลายเป็นความซับซ้อนและมีความเสี่ยง: คุณ
อาจได้รับเป็นครั้งแรก แต่ไม่ได้ล็อคที่สอง หรือสถานการณ์ที่หยุดชะงักอาจเกิดขึ้นหากคุณล็อคเดียวกัน
ล็อคในการสั่งซื้อที่แตกต่างกัน
ห้องสมุด C + + มาตรฐานจึงมีฟังก์ชั่นอำนวยความสะดวกในการพยายามที่จะล็อค mutexes หลาย
ตัวอย่างเช่น
std :: mutex m1;
std :: mutex m2;
. ..
{
std :: ล็อค (m1, m2) / / ล็อคทั้งสอง mutexes (หรือไม่ถ้าไม่ได้เป็นไปได้)
std :: lock_guardlockM1 (m1, std :: adopt_lock);
std :: lock_guardlockM2 (m2, std :: adopt_lock);
...
} / / ปลดล็อคโดยอัตโนมัติทั้งหมด mutexes
มาตรฐานทั่วโลก :: ล็อค () ล็อค mutexes ทั้งหมดผ่านอาร์กิวเมนต์ขวางจน mutexes ทั้งหมดจะถูก
ล็อคหรือจนกว่าจะมีข้อยกเว้น ในกรณีหลังนี้จะปลดล็อค mutexes แล้วประสบความสำเร็จใน
ล็อค ตามปกติหลังจากที่ล็อคที่ประสบความสำเร็จที่คุณสามารถและควรใช้ยามล็อคเริ่มต้นได้ด้วย
adopt_lock เป็นอาร์กิวเมนต์ที่สองเพื่อให้แน่ใจว่าในกรณีใด ๆ mutexes จะปลดล็อคเมื่อออกจาก
ขอบเขต โปรดทราบว่าล็อคนี้ () ให้เป็นกลไกที่หยุดชะงักหลีกเลี่ยงซึ่ง แต่หมายความ
ว่าคำสั่งของภายในล็อคล็อคหลายจะไม่ได้กำหนด
ในแบบเดียวกับที่คุณสามารถลองที่จะได้รับการล็อคหลายโดยไม่ปิดกั้นหากไม่ได้ล็อคทุกคนมีความ
สามารถ . มาตรฐานระดับโลก :: try_lock () กลับ -1 ถ้าล็อคทั้งหมดเป็นไปได้ ถ้าไม่กลับมา
เป็นค่าดัชนี zero-based ของล็อคล้มเหลวครั้งแรก ในกรณีที่ล็อคประสบความสำเร็จทั้งหมดจะถูกปลดล็อค
อีกครั้ง ตัวอย่างเช่น
std :: mutex m1;
std :: mutex m2;
IDX int = std :: try_lock (m1, m2) / / พยายามที่จะล็อคทั้งสอง mutexes
ถ้า (IDX <0) {/ / ล็อคทั้งสองประสบความสำเร็จ
std :: lock_guardlockM1 (m1, std :: adopt_lock);
std :: lock_guardlockM2 (m2, std :: adopt_lock);
...
} / / ปลดล็อคโดยอัตโนมัติ mutexes ทั้งหมด
else {
/ / IDX ได้ zero-based ดัชนีของครั้งแรกล้มเหลวล็อค
std :: cerr << "ไม่สามารถล็อค mutex เมตร" << IDX 1 << std :: endl;
}
โปรดทราบว่า try_lock นี้ () ไม่ได้ให้กลไกการหยุดชะงักหลีกเลี่ยง แต่จะรับประกัน
ว่าล็อคจะพยายามในการสั่งซื้อของการขัดแย้งผ่าน
หมายเหตุยังล็อคที่โทร () หรือ try_lock () โดยไม่ต้องใช้ล็อคโดยยามมักจะ
ไม่ได้สิ่งที่ตั้งใจ แม้ว่ารหัสดูเหมือนว่ามันจะสร้างล็อคที่ถูกปล่อยออกมาโดยอัตโนมัติ
เมื่อออกจากขอบเขตนี้เป็นกรณีที่ไม่ mutexes จะยังคงล็อค:
www.it-ebooks.info
996 บทที่ 18: Concurrency
std :: mutex m1;
std :: mutex m2;
...
{
std :: ล็อค (m1, m2) / / ล็อค mutexes ทั้งสอง ( หรือไม่มีถ้าไม่ได้เป็นไปได้)
/ / ล็อคไม่นำมาใช้
...
}
... / / OOPS!! mutexes จะถูกล็อคยังคง
unique_lock ชั้น
นอกจากชั้น lock_guard <> C + + ห้องสมุดมาตรฐานให้ unique_lock ชั้น <> ซึ่งเป็น
จำนวนมากที่มีความยืดหยุ่นมากขึ้นเมื่อต้องรับมือกับการล็อค mutexes ชั้น unique_lock <> ให้เดียวกัน
อินเตอร์เฟซเป็นชั้น lock_guard <> บวกกับความสามารถในการเขียนโปรแกรมอย่างชัดเจนเมื่อใดและวิธีการล็อคหรือ
ปลดล็อค mutex ของ ดังนั้นวัตถุล็อคนี้อาจจะหรืออาจจะไม่ได้ถูกล็อค mutex (หรือเรียกว่าการเป็นเจ้าของ
mutex) ซึ่งแตกต่างจาก lock_guard <> ซึ่งมักจะมีวัตถุล็อคตลอดของ
lifetime.21 นอกจากนี้สำหรับล็อคที่ไม่ซ้ำกันคุณสามารถค้นหาว่า mutex ถูกล็อกในปัจจุบันโดย
การเรียก owns_lock () หรือบูลผู้ประกอบการ ()
ได้เปรียบที่สำคัญของเรื่องนี้ ชั้นยังคงเป็นที่ว่าเมื่อ mutex ถูกล็อคในเวลาที่ถูกทำลาย
โดยอัตโนมัติเรียก destructor ปลดล็อค () สำหรับมัน ถ้าไม่มี mutex ถูกล็อค destructor ไม่ทำอะไรเลย
เมื่อเทียบกับ lock_guard ชั้น unique_lock ชั้นให้เสริมต่อไปนี้
การก่อสร้าง:
•คุณสามารถผ่าน try_to_lock สำหรับความพยายาม nonblocking เพื่อล็อค mutex:
std :: unique_lockล็อค (mutex, std :: try_to_lock);
...
ถ้า (ล็อค) {/ / ถ้าล็อคที่ประสบความสำเร็จ
...
}
•คุณสามารถส่งผ่านระยะเวลาหรือ timepoint ที่จะสร้างการพยายามที่จะล็อคระยะเวลาที่กำหนดของเวลา
std :: unique_lockล็อค (mutex,
std :: โครโนกราฟ :: วินาที (1));
...
•คุณสามารถผ่าน defer_lock เพื่อเริ่มต้นการล็อคโดยไม่ต้องล็อค mutex (ยัง):
std :: unique_lockล็อค (mutex, std :: defer_lock);
...
lock.lock () / / หรือ (หมดเวลา) try_lock ()
...
21 ชื่อล็อคที่ไม่ซ้ำกันที่จะอธิบายพฤติกรรมนี้มาจาก เช่นเดียวกับคำแนะนำที่ไม่ซ้ำกัน (ดูมาตรา 5.2.5,
หน้า 98) คุณสามารถย้ายล็อคระหว่างขอบเขต แต่จะรับประกันว่ามีเพียงหนึ่งล็อคในเวลาที่เป็นเจ้าของ mutex
www.it
การแปล กรุณารอสักครู่..
ผลลัพธ์ (ไทย) 3:[สำเนา]
คัดลอก!
บทที่ 18 : การจัดงาน
ประสานออกในทางที่แต่ละคนเรียก print() เฉพาะเขียนตัวอักษรของเรา
แนะนำ mutex สำหรับงานพิมพ์ และล็อคยามที่ล็อคที่ป้องกันส่วน std : : :

mutex printmutex ; / / ให้ตรงกันกับ print() ออก

ช่องว่างพิมพ์ . . . . . . . ( Const std : : สาย& S )
{
std : : lock_guard < std : : mutex > L ( printmutex ) ;
}

. . . . . . .ตอนนี้ ออก เป็น เพียง อะไรแบบนี้ :

สวัสดีสวัสดีจากกระทู้แรกจากกระทู้หลัก

สวัสดีจากหัวข้อที่สอง ผลลัพธ์นี้ยังเป็นไปได้ ( แต่ไม่รับประกัน ) เมื่อไม่มีล็อคใช้ .
ที่นี่ lock() ของ mutex ที่เรียกว่าโดยผู้สร้างของยาม ล็อก บล็อก ถ้า ทรัพยากร
ได้มาแล้ว มันบล็อกจนเข้าถึงความคุ้มครองส่วนจะพร้อมใช้งานอีกครั้ง อย่างไรก็ตาม
สั่งล็อคยังไม่ได้กำหนด . ดังนั้น , สามผล ยังอาจจะเขียนในคำสั่งโดยพลการ ล็อก

recursive บางครั้งความสามารถในการล็อค recursively จะต้อง ตัวอย่างทั่วไปเป็นวัตถุที่ใช้งานหรือตรวจสอบ
ซึ่งประกอบด้วย mutex และใช้ล็อคภายในรัฐทุกวิธีเพื่อปกป้องข้อมูลแข่งหาย
สภาพภายในของวัตถุ ตัวอย่างเช่นส่วนติดต่อฐานข้อมูลอาจมีลักษณะดังนี้ databaseaccess {


เรียนเอกชน :
std : : mutex dbmutex ;
. . . . . . . / / สภาพ : สร้างตารางฐานข้อมูล

โมฆะสาธารณะ ( . . . )
{
std : : lock_guard < std : : mutex > LG ( dbmutex ) ;
.
}
{ โมฆะ insertdata ( . . . )

: : : lock_guard < std : : mutex > LG ( dbmutex ) ;

. . . . . . . }
.
} ;
www.it-ebooks ข้อมูล 18.5 mutexes และล็อคได้

เมื่อเราแนะนำสมาชิกสาธารณะฟังก์ชันที่อาจจะเรียกฟังก์ชันสมาชิกสาธารณะอื่น ๆ นี้สามารถกลายเป็นความซับซ้อน createtableandinsertdata

: ช่องว่าง ( . . . )
{
std : : lock_guard < std : : mutex > LG ( dbmutex ) ;
.
สร้างตาราง ( . . . ) ; / / ข้อผิดพลาด : การหยุดชะงักเพราะถูกขังอยู่อีก
dbmutex }
เรียก createtableandinsertdata() จะมีผลในการหยุดชะงักเพราะหลังจากที่ล็อค dbmutex
,โทรของ createtable() จะพยายามล็อค dbmutex อีกครั้ง ซึ่งจะปิดกั้นจนล็อค
dbmutex สามารถใช้ได้ซึ่งจะไม่เกิดขึ้น เพราะ createtableandinsertdata() จะบล็อก

จน createtable() เสร็จ มาตรฐานห้องสมุดอนุญาตวินาทีที่จะโยนเป็น std : : system_error ( ดูมาตรา
ใน , หน้า 43 ) กับ รหัสข้อผิดพลาด resource_deadlock_would_occur ( ดูมาตรา 4.3.2
,หน้า 45 ) ถ้าแพลตฟอร์มที่ตรวจพบ เช่น การหยุดชะงัก แต่มันไม่จําเป็น และมักจะไม่กรณี .
โดยใช้ recursive_mutex พฤติกรรมนี้จะไม่มีปัญหา mutex นี้ช่วยให้ล็อคหลาย
ด้วยด้ายเหมือนกัน และปล่อยล็อค เมื่อสุดท้าย เรียก unlock() สอดคล้องกันเรียกว่า :


ส่วนตัวเรียน databaseaccess { :
std : : recursive_mutex dbmutex ;
. . . . . . . / / สถานะของฐานข้อมูลสาธารณะ :

โมฆะ insertdata ( . . . )
{
std : : lock_guard < std : : recursive_mutex > LG ( dbmutex ) ;
.
}
{ โมฆะ insertdata ( . . . )

: : : lock_guard < std : : recursive_mutex > LG ( dbmutex ) ;
.
}
เป็นโมฆะ createtableandinsertdata {

( . . . ) : : : lock_guard < std : : recursive_mutex > LG ( dbmutex ) ;
.
สร้างตาราง ( . . . ) ; / / โอเค ไม่มีการหยุดชะงัก
}
.
} ;
www.it-ebooks ข้อมูล
994 บทที่ 18 : การพยายามล็อก

,บางครั้งโปรแกรมต้องการที่จะได้รับล็อคแต่ไม่อยากปิดกั้น ( ตลอดไป ) ถ้าไม่ได้
ที่สุด สำหรับสถานการณ์นี้ mutexes ให้ try_lock() ฟังก์ชันสมาชิกที่พยายามที่จะได้รับ
ล็อค ถ้ามันประสบความสำเร็จ มันกลับจริง ; ถ้าไม่เท็จ .
ยังสามารถใช้ lock_guard เพื่อที่ออกจากขอบเขตปัจจุบันปลดล็อค mutex
,คุณสามารถผ่าน adopt_lock อาร์กิวเมนต์เพิ่มเติมของผู้สร้าง :
std : : mutex M ;
/ / พยายามที่จะได้รับล็อคและทำสิ่งอื่น ๆในขณะที่มันเป็นไปไม่ได้
ในขณะที่ ( ม. try_lock() = = เท็จ ) {

}
dosomeotherstuff() ; std : : lock_guard < std : : mutex > LG ( ม. , std : : adopt_lock ) ;
.
ทราบว่า try_lock() อาจล้มเหลว spuriously . คือมันอาจจะล้มเหลว ( กลับเท็จ ) ถ้าล็อค 20

ไม่ถ่ายจะรอแต่เงินที่เฉพาะเจาะจงของเวลาที่คุณสามารถใช้เวลา mutex . เรียนพิเศษ mutex
std : : timed_mutex std : : recursive_timed_mutex และยังอนุญาตให้เรียก
try_lock_for() หรือ try_lock_until() รอคอยมากที่สุดที่ระบุระยะเวลาของเวลาหรือจนกว่า
ระบุจุด เวลามาถึงแล้ว นี้ ตัวอย่างเช่น อาจจะช่วยได้ถ้าคุณมีความต้องการ
แบบเรียลไทม์หรือต้องการหลีกเลี่ยงสถานการณ์ที่หยุดชะงักไปได้ ตัวอย่าง :
: : : timed_mutex M ;
/ / ลองซักวินาทีที่จะได้รับล็อค
ถ้า ( m.try_lock_for ( std : : Chrono : : วินาที ( 1 ) ) ) ) ) ) ) {
std : : lock_guard < std : : timed_mutex > LG ( M , std : : adopt_lock ) ;

} . . .

couldnotgetthelock() อีก { ;
}
ทราบว่า try_lock_for() try_lock_until() และมักจะแตกต่างกัน เมื่อจัดการกับ systemtime
ปรับ ( ดู มาตรา 5.7.5 , หน้า 160 ,สำหรับรายละเอียด )

มักจะเกี่ยวข้องกับล็อคหลายหัวข้อควรล็อคเดียว mutex ครั้ง แต่บางครั้งมันก็ต้องล็อค
มากกว่าหนึ่ง mutex ( ตัวอย่างเช่น การถ่ายโอนข้อมูลจากการป้องกันทรัพยากรอื่น ) ใน
20 พฤติกรรมนี้มีไว้สำหรับหน่วยความจำสั่งซื้อเหตุผล แต่ยังไม่แพร่หลาย ขอบคุณฮันส์โบมและ
bartosz milewski สำหรับชี้ออก .
wwwมันอี - บุ๊ค ข้อมูล mutexes และล็อค 995

8 คดีที่เกี่ยวข้องกับกลไกล็อคที่แนะนำจนสามารถกลายเป็นความซับซ้อนและความเสี่ยง : คุณ
อาจได้ก่อน แต่ไม่ได้ล็อคที่สอง หรือชะงักงัน สถานการณ์อาจเกิดขึ้นถ้าคุณล็อคล็อคเดียวกัน
ในการสั่งซื้อที่แตกต่างกัน .
c มาตรฐานห้องสมุด ดังนั้น มีฟังก์ชั่นที่สะดวกลองล็อคหลาย mutexes .
ตัวอย่างเช่น std : : :

: : : mutex M1 ;mutex M2 { ;
. . . . . . .

std : : ล็อค ( M1 , M2 ) ; / / ล็อคทั้ง mutexes ( หรือไม่ถ้าไม่ที่สุด )
std : : lock_guard < std : : mutex > lockm1 ( M1 , std : : adopt_lock ) ;
std : : lock_guard < std : : mutex > lockm2 ( m2 std : : adopt_lock ) ;
.
} / / ปลดล็อคโดยอัตโนมัติทั้งหมด mutexes
( STD : : lock() ล็อคทั้งหมด mutexes ผ่านเป็นอาร์กิวเมนต์ที่ปิดกั้นจน mutexes เป็น
ล็อคหรือจนกว่าข้อยกเว้นคือโยน ในกรณีหลัง ,แล้วมันปลดล็อค mutexes เรียบร้อยแล้ว
ล็อค ตามปกติ หลังจากที่ประสบความสําเร็จล็อค , ที่คุณสามารถและควรจะใช้ล็อคยามเริ่มต้นด้วย
adopt_lock เป็นอาร์กิวเมนต์ที่สองเพื่อให้แน่ใจว่า ในกรณีใด ๆ , mutexes จะปลดล็อคเมื่อออกจาก
ขอบเขต . ทราบว่า lock() นี้ให้หยุดชะงักการหลีกเลี่ยงกลไก ซึ่ง แต่หมายถึงว่า คำสั่งของ
ล็อคหลายล็อคภายในเป็น God .
ในลักษณะเดียวกัน คุณสามารถพยายามที่จะได้รับล็อคหลายโดยไม่ปิดกั้น ถ้าล็อคไม่ได้ทั้งหมด
พร้อม มาตรฐานระดับโลก : : try_lock() ส่งกลับ - 1 ถ้าล็อคทั้งหมดเป็นไปได้ ถ้าไม่ กลับค่า
เป็นศูนย์ตามดัชนีของแรกล้มเหลวในการล็อค ในกรณีนั้น ประสบความสำเร็จ ล็อค ปลดล็อค
อีกครั้ง ตัวอย่าง : : : : mutex M1
;
std : : mutex M2 ;
1 IDX = std : : try_lock ( M1 , M2 )/ / พยายามล็อคทั้ง mutexes
ถ้า ( IDX < 0 ) { / / ทั้งล็อคสำเร็จ
std : : lock_guard < std : : mutex > lockm1 ( M1 , std : : adopt_lock ) ;
std : : lock_guard < std : : mutex > lockm2 ( m2 std : : adopt_lock ) ;
. . . . . . .
} / / ปลดล็อคโดยอัตโนมัติทั้งหมด mutexes
อีก {
/ / IDX มีศูนย์ตามดัชนีแรกล้มเหลวล็อค
std : : cerr < < " ไม่สามารถล็อค mutex M " < < IDX 1 < < std : : Endl }

;ทราบว่า try_lock() นี้ไม่ได้ให้หยุดชะงักการหลีกเลี่ยงกลไก แต่มันรับประกัน
ที่ล็อคเป็นพยายามในการสั่งซื้อของผ่านอาร์กิวเมนต์ .
นอกจากนั้น เรียก lock() หรือ try_lock() โดยไม่ใช้กุญแจจากยามปกติ
ไม่ใช่สิ่งที่ฉันตั้งใจไว้ แต่ดูเหมือนมันจะสร้างรหัสล็อคที่ถูกปล่อยออกมาโดยอัตโนมัติ
เมื่อออกจากขอบเขตนี้เป็นกรณีที่ไม่ การ mutexes จะยังคงล็อค :
www.it-ebooks ข้อมูล
996 บทที่ 18 : การ mutex std : :

: : : mutex M1 ; M2 { ;
. . . . . . .

std : : ล็อค ( M1 , M2 ) ; / / ล็อคทั้ง mutexes ( หรือไม่ถ้าไม่ที่สุด )

/ / ไม่มีล็อคบุญธรรม . . . . . . .
}
. . . . . . . / / โอ๊ะโอ : mutexes ยังล็อคอยู่ ! ! ! ! ! ! !

นอกจากคลาสเรียน unique_lock lock_guard < > , มาตรฐานห้องสมุดให้ชั้นเรียน unique_lock
< > ซึ่งเป็นเพิ่มเติมมีความยืดหยุ่นมากเมื่อจัดการกับล็อก mutexes . ชั้น unique_lock < > มีอินเตอร์เฟซเดียวกัน
เป็นคลาส lock_guard < > บวกกับความสามารถในการโปรแกรมอย่างชัดเจนเมื่อและวิธีการล็อคหรือปลดล็อคของ mutex
. นี่ล็อควัตถุที่อาจจะหรืออาจจะไม่ได้มี mutex ล็อค ( หรือที่เรียกว่าการเป็นเจ้าของการ mutex ) นี้แตกต่างจาก lock_guard < > ซึ่งมักจะมีวัตถุล็อคตลอดช่วงชีวิตของมัน

21 นอกจากนี้ สำหรับล็อคที่ไม่ซ้ำกันคุณสามารถค้นหาว่า mutex ปัจจุบันถูกล็อคโดย
เรียก owns_lock() หรือผู้ประกอบการ bool() .
ข้อดีหลักของชั้นนี้ยังเป็นเมื่อ mutex ถูกล็อคในเวลาทำลาย ,
เดสทรัคเตอร์โดยอัตโนมัติเรียก unlock() สำหรับมัน ถ้าไม่ mutex ล็อค , เดสทรัคเตอร์ ไม่ทำอะไร เมื่อเทียบกับระดับ lock_guard
,ชั้น unique_lock ให้เพิ่มเติมต่อไปนี้ :
-
การก่อสร้างคุณสามารถผ่าน try_to_lock สำหรับ nonblocking พยายามล็อค mutex :
std : : unique_lock < std : : mutex > ล็อค ( mutex , std : : try_to_lock ) ;
.
ถ้า ( ล็อค ) { / / ถ้าล็อคประสบความสำเร็จ


} . . . - คุณสามารถผ่านช่วงเวลาหรือ timepoint ไปกําหนดเพื่อพยายามที่จะล็อคให้เฉพาะระยะเวลา :
std : : unique_lock < std : : timed_mutex > ( mutex ล็อค ,
std : : Chrono : : วินาที ( 1 ) ;
-
. . . . . . . คุณสามารถผ่าน defer_lock เริ่มล็อคโดยไม่ต้องล็อก mutex ( ยัง ) :
std : : unique_lock < std : : mutex > ล็อค ( mutex , std : : defer_lock ) ;
.
ล็อค lock() ; / / หรือ ( หมด ) try_lock()
.
21 ชื่อเฉพาะล็อคอธิบายว่าพฤติกรรมนี้มาจาก เป็นเฉพาะกับตัวชี้ ( ดูมาตรา 5.2.5
, หน้า 98 ) , คุณสามารถย้ายล็อคระหว่างกล้องแต่ก็รับประกันได้ว่าเพียงหนึ่งล็อคเวลาที่เจ้าของ mutex .
www.it
การแปล กรุณารอสักครู่..
 
ภาษาอื่น ๆ
การสนับสนุนเครื่องมือแปลภาษา: กรีก, กันนาดา, กาลิเชียน, คลิงออน, คอร์สิกา, คาซัค, คาตาลัน, คินยารวันดา, คีร์กิซ, คุชราต, จอร์เจีย, จีน, จีนดั้งเดิม, ชวา, ชิเชวา, ซามัว, ซีบัวโน, ซุนดา, ซูลู, ญี่ปุ่น, ดัตช์, ตรวจหาภาษา, ตุรกี, ทมิฬ, ทาจิก, ทาทาร์, นอร์เวย์, บอสเนีย, บัลแกเรีย, บาสก์, ปัญจาป, ฝรั่งเศส, พาชตู, ฟริเชียน, ฟินแลนด์, ฟิลิปปินส์, ภาษาอินโดนีเซี, มองโกเลีย, มัลทีส, มาซีโดเนีย, มาราฐี, มาลากาซี, มาลายาลัม, มาเลย์, ม้ง, ยิดดิช, ยูเครน, รัสเซีย, ละติน, ลักเซมเบิร์ก, ลัตเวีย, ลาว, ลิทัวเนีย, สวาฮิลี, สวีเดน, สิงหล, สินธี, สเปน, สโลวัก, สโลวีเนีย, อังกฤษ, อัมฮาริก, อาร์เซอร์ไบจัน, อาร์เมเนีย, อาหรับ, อิกโบ, อิตาลี, อุยกูร์, อุสเบกิสถาน, อูรดู, ฮังการี, ฮัวซา, ฮาวาย, ฮินดี, ฮีบรู, เกลิกสกอต, เกาหลี, เขมร, เคิร์ด, เช็ก, เซอร์เบียน, เซโซโท, เดนมาร์ก, เตลูกู, เติร์กเมน, เนปาล, เบงกอล, เบลารุส, เปอร์เซีย, เมารี, เมียนมา (พม่า), เยอรมัน, เวลส์, เวียดนาม, เอสเปอแรนโต, เอสโทเนีย, เฮติครีโอล, แอฟริกา, แอลเบเนีย, โคซา, โครเอเชีย, โชนา, โซมาลี, โปรตุเกส, โปแลนด์, โยรูบา, โรมาเนีย, โอเดีย (โอริยา), ไทย, ไอซ์แลนด์, ไอร์แลนด์, การแปลภาษา.

Copyright ©2026 I Love Translation. All reserved.

E-mail: