18.5 Mutexes and Locks 997The defer_lock flag can, for example, be use การแปล - 18.5 Mutexes and Locks 997The defer_lock flag can, for example, be use ไทย วิธีการพูด

18.5 Mutexes and Locks 997The defer

18.5 Mutexes and Locks 997
The defer_lock flag can, for example, be used to create one or multiple locks and lock them later:
std::mutex m1;
std::mutex m2;
std::unique_lock lockM1(m1,std::defer_lock);
std::unique_lock lockM2(m2,std::defer_lock);
...
std::lock (m1, m2); // lock both mutexes (or none if not possible)
In addition, class unique_lock provides the ability to release() its mutex or to transfer the ownership
of a mutex to another lock. See Section 18.5.2, page 1000, for details.
With both a lock_guard and a unique_lock, we can now implement a naive example, where
one thread waits for another by polling a ready flag:
#include
...
bool readyFlag;
std::mutex readyFlagMutex;
void thread1()
{
// do something thread2 needs as preparation
...
std::lock_guard lg(readyFlagMutex);
readyFlag = true;
}
void thread2()
{
// wait until readyFlag is true (thread1 is done)
{
std::unique_lock ul(readyFlagMutex);
while (!readyFlag) {
ul.unlock();
std::this_thread::yield(); // hint to reschedule to the next thread
std::this_thread::sleep_for(std::chrono::milliseconds(100));
ul.lock();
}
} // release lock
// do whatever shall happen after thread1 has prepared things
...
}
www.it-ebooks.info
998 Chapter 18: Concurrency
Two comments on typical questions this code might raise:
• If you wonder why we use a mutex to control the access to read and write the readyFlag,
remember the rule introduced at the beginning of this chapter: Any concurrent access with at
least one write should be synchronized. See Section 18.4, page 982, and Section 18.7, page 1012,
for a detailed discussion about this.
• If you wonder that no volatile is necessary here to declare readyFlag to avoid that multiple
attempts in thread2() to read it are not optimized away note the following: These attempts to
read readyFlag happen inside a critical section, defined between the setting and releasing of
a lock. Such code is not allowed to get optimized in a way that the read (or a write) is moved
outside the critical section. So the reads of readyFlag must effectively happen here:
– At the beginning of the loop, between the declaration of ul and the first call of unlock()
– Inside the loop, between any call of lock() and unlock()
– At the end of the loop, between the last call of lock() and the destruction of ul, which
unlocks the mutex if locked
Nevertheless, such a polling for a fulfilled condition is usually not a good solution. A better approach
is to use condition variables. See Section 18.6.1, page 1003, for details.
18.5.2 Mutexes and Locks in Detail
Mutexes in Detail
The C++ standard library provides the following mutex classes (see Table 18.6):
• Class std::mutex is a simple mutex that can be locked only once by one thread at a time. If it
is locked, any other lock() will block until the mutex is available again and try_lock() will
fail.
• Class std::recursive_mutex is a mutex that allows multiple locks at the same time by
the same thread. The typical application of such a lock is where functions acquire a lock and
internally call another function, which also acquires the same lock again.
Operation mutex recursive_
mutex
timed_mutex recursive_
timed_mutex
lock() Acquires mutex (blocks if not available)
try_lock() Acquires mutex (returns false if not available)
unlock() Unlocks locked mutex
try_lock_for() – – Tries to acquire a lock for a duration of time
try_lock_until() – – Tries to acquire a lock until a timepoint
multiple locks No Yes
(same thread)
No Yes
(same thread)
Table 18.6. Overview of Mutexes and Their Abilities
www.it-ebooks.info
18.5 Mutexes and Locks 999
• Class std::timed_mutex is a simple mutex that additionally allows you to pass a duration
or a timepoint that defines how long it tries to acquire a lock. For this, try_lock_for() and
try_lock_until() are provided.
• Class std::recursive_timed_mutex is a mutex that allows multiple locks by the same
thread with optional timeouts.
Table 18.7 lists the mutex operations, if available.
Operation Effect
mutex m Default constructor; creates an unlocked mutex
m.~mutex() Destroys the mutex (must not be locked)
m.lock() Locks the mutex (blocks for lock; error if locked and not
recursive)
m.try_lock() Tries to lock the mutex (returns true if lock successful)
m.try_lock_for(dur) Tries to lock for duration dur (returns true if lock
successful)
m.try_lock_until(tp) Tries to lock until timepoint tp (returns true if lock
successful)
m.unlock() Unlocks the mutex (undefined behavior if not locked)
m.native_handle() Returns a platform-specific type native_handle_type for
nonportable extensions
Table 18.7. Operations of Mutex Classes, If Available
lock() might throw a std::system_error (see Section 4.3.1, page 43) with the following error
codes (see Section 4.3.2, page 45):
• operation_not_permitted, if the thread does not have the privilege to perform the operation
• resource_deadlock_would_occur, if the platform detects that a deadlock would occur
• device_or_resource_busy, if the mutex is already locked and blocking is not possible
The behavior of a program is undefined if it unlocks a mutex object it doesn’t own, destroys a mutex
object owned by any thread, or if a thread terminates while owning a mutex object.
Note that try_lock_for() and try_lock_until() usually will differ when dealing with
system-time adjustments (see Section 5.7.5, page 160, for details).
Class lock_guard in Detail
Class std::lock_guard, introduced in Section 18.5.1, page 989, provides a very small interface to
ensure that a locked mutex gets always freed when leaving the scope (see Table 18.8). Throughout
its lifetime, it is always associated with a lock either explicitly requested or adopted at construction
time.
www.it-ebooks.info
1000 Chapter 18: Concurrency
Operation Effect
lock_guard lg(m) Creates a lock guard for the mutex m and locks it
lock_guard lg(m,adopt_lock) Creates a lock guard for the already locked mutex m
lg.~lock_guard() Unlocks the mutex and destroys the lock guard
Table 18.8. Operations of Class lock_guard
Class unique_lock in Detail
Class std::unique_lock, introduced in Section 18.5.1, page 996, provides a lock guard for a mutex
that does not necessarily have to be locked (owned). It provides the interface listed in Table 18.9.
If it locks/owns a mutex at destruction time, it will unlock() it. But you can control explicitly
whether it has an associated mutex and whether this mutex is locked. You can also try to lock the
mutex with or without timeouts.
lock() might throw a std::system_error (see Section 4.3.1, page 43) with the error codes
listed for lock() for mutexes (see page 999). unlock() might throw a std::system_error with
the error code operation_not_permitted if the unique lock isn’t locked.
18.5.3 Calling Once for Multiple Threads
Sometimes multiple threads might not need some functionality that should get processed whenever
the first thread needs it. A typical example is lazy initialization: The first time one of the threads
needs something that has to get processed, you process it (but not before, because you want to save
the time to process it if it is not needed).
The usual approach with single-threaded environments is simple: A Boolean flag signals whether
the functionality was called already:
bool initialized = false; // global flag
...
if (!initialized) { // initialize if not initialized yet
initialize();
initialized = true;
}
or
static std::vector staticData;
void foo()
{
if (staticData.empty()) {
staticData = initializeStaticData();
}
...
}
www.it-ebooks.info
18.5 Mutexes and Locks 1001
Operation Effect
unique_lock l Default constructor; creates a lock not associated with a
mutex
unique_lock l(m) Creates a lock guard for the mutex m and locks it
unique_lock l(m,adopt_lock) Creates a lock guard for the already locked mutex m
unique_lock l(m,defer_lock) Creates a lock guard for the mutex m without locking it
unique_lock l(m,try_lock) Creates a lock guard for the mutex m and tries to lock it
unique_lock l(m,dur) Creates a lock guard for the mutex m and tries to lock it for
duration dur
unique_lock l(m,tp) Creates a lock guard for the mutex m and tries to lock it
until timepoint tp
unique_lock l(rv) Move constructor; moves lock state from rv to l (rv has no
associated mutex anymore)
l.~unique_lock() Unlocks the mutex, if any locked, and destroys the lock
guard
unique_lock l = rv Move assignment; moves the lock state from rv to l (rv has
no associated mutex anymore)
swap(l1,l2) Swaps locks
l1.swap(l2) Swaps locks
l.release() Returns a pointer to the associated mutex and releases it
l.owns_lock() Returns true if an associated mutex is locked
if (l) Checks whether an associated mutex is locked
l.mutex() Returns a pointer to the associated mutex
l.lock() Locks the associated mutex
l.try_lock() Tries to lock the associated mutex (returns true if lock
successful)
l.try_lock_for(dur) Tries to lock the associated mutex for duration dur (returns
true if lock successful)
l.try_lock_until(tp) Tries to lock the associated mutex until timepoint tp
(returns true if lock successful)
l.unlock() Unlocks the associated mutex
Table 18.9. Operations of Class unique_lock
Such code doesn’t work in a multithreaded context, because data races might occur if two or more
threads check whether the initialization didn’t happen yet and start the initialization then. Thus, you
have to protect the area for the check and the initialization against concurrent access.
As usual, you can use mutexes for it, but the C++ standard library provides a special solution
for this case. You simply use a std::once_flag and call std::call_once (also provided by
):
std::once_flag oc; // global flag
...
std::call_once(oc,initialize); // initialize if not initialized yet
www.it-ebooks.info
1002 Chapter 18: Concurrency
or:
static std::vector staticData;
void foo()
{
static std::once_flag oc;
std::call_once(oc,[]{
staticData = initializeSt
0/5000
จาก: -
เป็น: -
ผลลัพธ์ (ไทย) 1: [สำเนา]
คัดลอก!
18.5 Mutexes และล็อค 997
ธง defer_lock เช่น ใช้เพื่อสร้างหนึ่ง หรือหลายล็อค และล็อคภายหลัง:
std::mutex m1;
std::mutex m2;
std::unique_lock lockM1(m1,std::defer_lock);
std::unique_lock lockM2(m2,std::defer_lock);
...
std::lock (m1, m2); / / ล็อคทั้ง mutexes (หรือไม่ถ้าไม่ได้)
, คลา unique_lock ให้สามารถ release() ของ mutex หรือโอนย้ายเป็นเจ้า
ของ mutex ล็อคอื่น ดูส่วน 18.5.2 หน้า 1000 สำหรับรายละเอียด
ทั้ง lock_guard และ unique_lock เป็น เราสามารถตอนนี้ใช้ตัวอย่างขำน่า ที่
เธรดหนึ่งรออีก โดยสำรวจธงพร้อม:
#include
...
bool readyFlag;
std::mutex readyFlagMutex;
ยกเลิก thread1()
{
/ / ทำอะไร thread2 ต้องเป็นเตรียม
...
std::lock_guard lg (readyFlagMutex);
readyFlag = true;
}
ยกเลิก thread2()
{
/ / รอ readyFlag เป็นจริง (thread1 เสร็จสิ้น)
{
std::unique_lock ul (readyFlagMutex);
ขณะ (! readyFlag) {
ul.unlock();
std::this_thread::yield(); / / แย้มการจัดกำหนดการใหม่เพื่อ thread
std::this_thread::sleep_for(std::chrono::milliseconds(100)) ถัดไป;
ul.lock();
}
} / / ปลดล็อก
/ / ทำสิ่งที่จะเกิดขึ้นหลังจาก thread1 ได้เตรียมสิ่ง
...
}
www.it-ebooks.info
998 บท 18: เกิด
2 ความคิดเห็นเกี่ยวกับคำถามทั่วไปรหัสนี้อาจเพิ่ม:
•หากคุณสงสัยว่า ทำไมเราใช้ mutex ที่เพื่อควบคุมการเข้าถึงอ่าน และเขียน readyFlag,
จำกฎที่แนะนำในตอนต้นของบทนี้: สามารถเข้าพร้อมกันกับที่
ควรซิงโครไนส์เขียนอย่างน้อยหนึ่ง ดูส่วน 18.4 หน้า 982 และส่วน 18.7 หน้า 1012,
สำหรับสนทนารายละเอียดเกี่ยวกับเรื่องนี้
•หากคุณสงสัยว่า ระเหยไม่จำเป็นนี่ประกาศ readyFlag เพื่อหลีกเลี่ยงหลายที่
thread2() การพยายามจะไม่เพิ่มประสิทธิภาพไปอ่านหมายเหตุต่อไปนี้: เหล่านี้พยายาม
อ่าน readyFlag เกิดขึ้นภายในส่วนที่สำคัญ กำหนดขึ้นระหว่างการตั้งค่าและการปล่อยของ
ล็อค รหัสดังกล่าวไม่ได้รับอนุญาตให้ได้รับการปรับในลักษณะที่อ่าน (หรือเขียนเป็น) ถูกย้าย
นอกส่วนสำคัญ เพื่อให้ผู้อ่านของ readyFlag ต้องเกิดขึ้นอย่างมีประสิทธิภาพนี่:
– ต้นลูป ระหว่างรายงานของ ul และเรียกแรกปลดล็อก()
– ภาย ใน ลูป ระหว่างโทรของ lock() และ unlock()
– ที่สุดของลูป ระหว่างการโทรล่าสุดของ lock() และทำลายของ ul ซึ่ง
ปลดล็อก mutex ถ้าล็อก
อย่างไรก็ตาม โพลล์ดังกล่าวการสำหรับเงื่อนไขการดำเนินไม่มักจะเป็นโซลูชันที่ดี วิธีที่ดีกว่า
จะใช้เงื่อนไขตัวแปร ดูส่วน 18.6.1, 1003 หน้าสำหรับรายละเอียด
18.5.2 Mutexes และล็อครายละเอียด
Mutexes ละเอียด
ไลบรารีมาตรฐาน C มี mutex คลาดังต่อไปนี้ (ดูตารางที่ 18.6):
std::mutex •คลามี mutex ง่ายที่สามารถล็อคเพียงครั้งเดียว โดยหัวข้อหนึ่งที่ ถ้ามัน
เป็นล็อค lock() อื่น ๆ จะบล็อก mutex จะพร้อมใช้งานอีกครั้ง และจะ try_lock()
ล้มเหลว
std::recursive_mutex •คลาสมี mutex ที่ล็อคหลายในเวลาเดียวกันโดย
หัวข้อเดียวกัน แอพลิเคชันทั่วไปของล็อคดังกล่าวอยู่ที่ฟังก์ชั่นการบล็อค และ
เรียกฟังก์ชันอื่น ซึ่งยัง ได้ฝึกฝนการล็อกเดียวกันอีกภายใน.
ดำเนิน mutex recursive_
mutex
timed_mutex recursive_
timed_mutex
lock() Acquires mutex (บล็อกถ้าไม่ available)
try_lock() Acquires mutex (คืนค่าเท็จถ้าไม่ available)
unlock() mutex Unlocks ล็อก
try_lock_for() – –พยายามการบล็อคสำหรับระยะเวลา time
try_lock_until() – – พยายามการบล็อคจนเป็น timepoint
หลายล็อคไม่ใช่
(same thread)

(same thread) ไม่ใช่
18.6 ตาราง ภาพรวมของความสามารถของพวกเขาและ Mutexes
www.it-ebooks.info
18.5 Mutexes และล็อค 999
std::timed_mutex คลาส•มี mutex ง่ายที่ช่วยให้คุณผ่านช่วงนอกจากนี้
หรือ timepoint ที่กำหนดระยะพยายามการบล็อค นี้ try_lock_for() and
try_lock_until() มี.
std::recursive_timed_mutex •คลาสมี mutex ที่ล็อคหลาย โดยตรง
ด้าย ด้วยเพิ่มเติมหมดเวลาการ
18.7 ตารางแสดงรายการการดำเนินงานของ mutex ถ้ามี.
ผลการดำเนินงาน
mutex m เริ่มต้นตัวสร้าง สร้างมี mutex ปลด
m~mutex() ทำลาย mutex (ต้องมี mutex ล็อค locked)
m.lock() (บล็อกสำหรับล็อค ข้อผิดพลาดถ้าล็อก และ not
recursive)
m.try_lock() พยายามล็อก mutex (ถ้าจริงกลับล็อก successful)
m.try_lock_for(dur) พยายามล็อคสำหรับ dur ระยะเวลา (คืนค่าจริงถ้าพยายามล็อคจนถึง timepoint tp lock
successful)
m.try_lock_until(tp) (ถ้าจริงกลับล็อค
ประสบความสำเร็จ)
munlock() ปลดล็อค mutex (ไม่ได้กำหนดลักษณะการทำงานถ้าไม่ locked)
m.native_handle() กลับ native_handle_type ชนิดเฉพาะของแพลตฟอร์มสำหรับ
นามสกุล nonportable
18.7 ตาราง การดำเนินงานของ Mutex ชั้น ถ้า Available
lock() อาจโยนเป็น std::system_error (ดูหัวข้อ 4.3.1 หน้า 43) ข้อผิดพลาดต่อไปนี้
รหัส (ดูหัวข้อ 4.3.2 หน้า 45):
• operation_not_permitted ถ้าหัวข้อไม่มีสิทธิ์ในการดำเนิน
resource_deadlock_would_occur • ถ้าแพลตฟอร์มตรวจพบว่า จะเกิดการล็อกตาย
device_or_resource_busy • mutex ถูกล็อค และบล็อกไม่ได้
ลักษณะการทำงานของโปรแกรมจะไม่ถ้ามันปลดล็อควัตถุ mutex ที่ไม่เอง ทำลายมี mutex
วัตถุที่เจ้าของกระทู้ใด ๆ, หรือ ถ้าหัวข้อการสิ้นสุดลงในขณะที่เป็นเจ้าของวัตถุ mutex
สังเกตว่า try_lock_for() และ try_lock_until() มักจะแตกต่างกันเมื่อเผชิญกับ
ปรับปรุงระบบเวลา (ดูส่วน 5.7.5 หน้า 160 รายละเอียด) .
lock_guard คลาในรายละเอียด
คลา std::lock_guard ในส่วน 18.5.1 หน้า 989 ให้อินเทอร์เฟซแบบเล็ก ๆ ไป
ให้แน่ใจว่า mutex ล็อคได้รับเสมอรอดเมื่อออกจากขอบเขต (ดูตารางที่ 18.8) ตลอด
รอบ เป็นเกี่ยวข้องกับล็อคชัดเจนร้องขอ หรือก่อสร้าง
เวลา
www.it-ebooks.info
1000 บทที่ 18: เกิด
ผลการดำเนินงาน
lock_guard lg(m) สร้างยามล็อคสำหรับ mutex m และล็อก
lg lock_guard (madopt_lock) สร้างยามล็อค m
lg.~lock_guard() mutex แล้วล็อคปลดล็อค mutex และทำลายยามล็อค
18.8 ตาราง การดำเนินงานของคลาส lock_guard
unique_lock คลาในรายละเอียด
คลา std::unique_lock ในส่วน 18.5.1, 996 หน้าแสดงยามล็อคมี mutex
ที่ไม่จำเป็นต้อง ล็อค (เจ้าของ) มีอินเทอร์เฟซที่ระบุไว้ในตารางที่ 18.9.
ถ้ามันล็อค/เป็นเจ้าของ mutex เป็นทำลายครั้ง มันจะ unlock() ก็ แต่สามารถควบคุมอย่างชัดเจน
ว่ามี mutex เกี่ยวข้องและว่า mutex นี้ถูกล็อก นอกจากนี้คุณยังสามารถลองล็อก
mutex หรือ ไม่ timeouts.
lock() อาจโยนเป็น std::system_error (ดูหัวข้อ 4.3.1 หน้า 43) กับรหัสข้อผิดพลาด
รายการสำหรับ lock() สำหรับ mutexes (ดูหน้า 999) unlock() อาจโยนเป็น std::system_error กับ
operation_not_permitted รหัสข้อผิดพลาดถ้าไม่ล็อคล็อคเฉพาะ.
18.5.3 เรียกหนึ่งครั้งสำหรับเธรดหลาย
บางครั้งหลายเธรดอาจไม่จำเป็นต้องทำงานบางอย่างที่ควรได้รับเมื่อใดก็ตามการประมวลผล
หัวข้อแรกต้องได้ ตัวอย่างทั่วไปคือ เริ่มขี้เกียจ: ครั้งหนึ่งเธรด
ต้องการสิ่งที่ได้รับการประมวลผล คุณประมวลผล (แต่ไม่ ก่อน เนื่องจากคุณต้องการบันทึก
เวลาในการประมวลผลถ้ามันไม่จำเป็น) .
วิธีปกติกับสภาพแวดล้อมแบบเธรดเดียวจะง่าย: A บูธงสัญญาณว่า
ฟังก์ชันถูกเรียกแล้ว:
bool ที่เริ่มต้น =เท็จ / / สากลธง
...
ถ้า (! เริ่มต้น) { / / เริ่มต้นถ้า ไม่เริ่มต้นยัง
เริ่มต้น();
เริ่มต้น =จริง;
}
หรือ
คงมาตรฐาน::เวกเตอร์ staticData;
โมฆะ(ฟู)
{
ถ้า (staticData.empty()) {
staticData = initializeStaticData();
}
...
}
www.it-ebooks.info
18.5 Mutexes และล็อค 1001
ผลการดำเนินงาน
unique_lock l เริ่มต้นตัวสร้าง สร้างล็อคไม่สัมพันธ์กับการ
mutex
unique_lock l(m) สร้างยามล็อคสำหรับ mutex m และล็อก
unique_lock (m, ladopt_lock) สร้างยามล็อคสำหรับ m mutex แล้วล็อค
unique_lock l(m,defer_lock) สร้างยามล็อคสำหรับ mutex m โดยมัน
unique_lock l(m,try_lock) สร้างยามล็อคสำหรับ mutex m และพยายามที่จะล็อคมัน
unique_lock l(m,dur) สร้างยามล็อคสำหรับ mutex m และพยายามที่จะล็อคไว้สำหรับ
dur ระยะเวลา
unique_lock l (m,tp) สร้างยามล็อคสำหรับ mutex m และพยายามที่จะล็อคมัน
จน timepoint tp
unique_lock l(rv) ย้ายตัวสร้าง ย้ายล็อคสถานะจาก rv l (ไม่มี rv
mutex สัมพันธ์ anymore)
l.~unique_lock() ปลดล็อค mutex ถ้ามีล็อค และทำลายล็อค
รักษา
unique_lock l = rv ย้ายกำหนด ย้ายสถานะล็อคจาก rv ไป l (rv มี
ไม่สัมพันธ์ mutex anymore)
swap(l1,l2) Swaps ล็อค
l1swap(l2) Swaps locks
l.release() ตัวชี้การ mutex สัมพันธ์ และรุ่น it
l.owns_lock() จริงล็อค mutex เชื่อมโยง
ถ้า (l) ตรวจดูว่า มี mutex สัมพันธ์ locked
l.mutex() ส่งกลับค่าตัวชี้การ mutex
l.lock() สัมพันธ์ล็อค mutex
l.try_lock() สัมพันธ์พยายามล็อก mutex เกี่ยวข้อง (ถ้าจริงกลับล็อค
สำเร็จ)
ltry_lock_for(dur) พยายามล็อก mutex เกี่ยวข้องสำหรับระยะเวลา dur (คืน
ถ้าจริงล็อค successful)
l.try_lock_until(tp) พยายามล็อก mutex เกี่ยวข้องจนถึง timepoint tp
(คืนค่าจริงถ้า successful)
l.unlock() ล็อคปลดล็อค mutex สัมพันธ์
18.9 ตาราง การดำเนินงานของคลาส unique_lock
รหัสดังกล่าวไม่ทำงานในบริบทให้ เนื่องจากการแข่งขันข้อมูลอาจเกิดขึ้นถ้าอย่าง น้อยสอง
หัวข้อตรวจสอบว่า การเริ่มต้นไม่เกิดขึ้นได้ และเริ่มต้นการเริ่มต้นแล้ว ดังนั้น คุณ
ต้องปกป้องพื้นที่สำหรับการตรวจสอบและการเริ่มต้นกับการเข้ากัน
ตามปกติ คุณสามารถใช้ mutexes มัน แต่ไลบรารีมาตรฐาน C ให้เป็นโซลูชั่นพิเศษ
สำหรับกรณีนี้ คุณเพียงแค่ใช้เป็น std::once_flag และโทร std::call_once (โดย
):
มาตรฐาน::once_flag องศาเซลเซียส / / สากล flag
...
std::call_once(oc,initialize) / / เริ่มต้นถ้า ไม่เริ่มต้นยัง
www.it-ebooks.info
1002 บท 18: เกิด
หรือ:
คง std::vector staticData;
โมฆะ(ฟู)
{
std::once_flag คงองศาเซลเซียส;
std::call_once(oc,[]{
staticData = initializeSt
การแปล กรุณารอสักครู่..
ผลลัพธ์ (ไทย) 2:[สำเนา]
คัดลอก!
18.5 mutexes และล็อค 997
ธง defer_lock สามารถยกตัวอย่างเช่นใช้ในการสร้างหนึ่งหรือหลายล็อคและล็อคพวกเขาในภายหลัง:
std :: mutex m1;
std :: mutex m2;
std :: unique_locklockM1 (m1, std :: defer_lock);
std :: unique_locklockM2 (m2, std :: defer_lock);
...
std :: ล็อค (m1, m2) / / ล็อคทั้งสอง mutexes (หรือไม่ถ้าไม่ได้เป็นไปได้)
นอกจากนี้ unique_lock ระดับความสามารถในการปล่อย () mutex หรือของ การถ่ายโอนความเป็นเจ้าของ
ของ mutex ที่จะล็อคอีก ดูมาตรา 18.5.2, หน้า 1000 สำหรับรายละเอียด
มีทั้ง lock_guard unique_lock และตอนนี้เราสามารถใช้เป็นตัวอย่างที่ไร้เดียงสาที่
ด้ายรออื่นโดยการลงคะแนนเลือกตั้งพร้อมธง:
# include
...
บูล readyFlag;
std :: mutex readyFlagMutex;
thread1 เป็นโมฆะ ()
{
/ / ทำสิ่งที่ thread2 ต้องเตรียม
...
std :: lock_guardแอลจี (readyFlagMutex);
readyFlag = true;
}
thread2 เป็นโมฆะ ()
{
/ / รอจนกว่า readyFlag เป็นจริง (thread1 จะทำ)
{
std :: unique_lockul (readyFlagMutex);
ในขณะที่ (readyFlag!) {
ul.unlock ();
std :: this_thread :: ผลผลิต () / / คำแนะนำในการจัดตารางการด้ายต่อไป
std :: this_thread :: sleep_for (std :: :: โครโนกราฟ มิลลิวินาที (100));
ul.lock ();
}
} / / ปลดล็อค
/ / ทำสิ่งที่จะเกิดขึ้นหลังจาก thread1 ได้จัดเตรียมสิ่งที่
...
}
www.it-ebooks.info
998 บทที่ 18: Concurrency
สองความคิดเห็นเกี่ยวกับคำถามทั่วไป รหัสนี้อาจยก:
•หากคุณสงสัยว่าทำไมเราใช้ mutex เพื่อควบคุมการเข้าถึงการอ่านและเขียน readyFlag,
จำกฎที่นำมาที่จุดเริ่มต้นของบทนี้: การเข้าถึงพร้อมกันใด ๆ ที่มีอย่าง
น้อยหนึ่งเขียนควรจะทำข้อมูลให้ตรงกัน ดูมาตรา 18.4, หน้า 982 และมาตรา 18.7, หน้า 1012
สำหรับการอภิปรายรายละเอียดเกี่ยวกับเรื่องนี้
•หากคุณสงสัยว่าจะไม่มีการเปลี่ยนแปลงเป็นสิ่งที่จำเป็นที่นี่เพื่อประกาศ readyFlag เพื่อหลีกเลี่ยงการที่หลาย
ความพยายามใน thread2 () เพื่ออ่านมันจะไม่เหมาะไป ทราบต่อไปนี้: ความพยายามเหล่านี้จะ
อ่าน readyFlag เกิดขึ้นในส่วนที่สำคัญที่กำหนดไว้ระหว่างการตั้งค่าและการปล่อยของ
ล็อค รหัสดังกล่าวจะไม่ได้รับอนุญาตที่จะได้รับการปรับให้เหมาะสมในทางที่อ่าน (หรือเขียน) จะถูกย้าย
ออกไปข้างนอกส่วนที่สำคัญ ดังนั้นอ่านของ readyFlag ได้อย่างมีประสิทธิภาพจะต้องเกิดขึ้นที่นี่:
- ที่จุดเริ่มต้นของห่วงระหว่างการประกาศของยูและสายแรกของการปลดล็อค ()
- ภายในห่วงระหว่างการเรียกร้องของการล็อคใด ๆ () และปลดล็อค ()
- ที่ ในตอนท้ายของห่วงระหว่างสายสุดท้ายของล็อค () และการล่มสลายของ ul ซึ่ง
ปลดล็อค mutex ถ้าล็อค
อย่างไรก็ตามเช่นการสำรวจสภาพปฏิบัติมักจะไม่เป็นทางออกที่ดี วิธีที่ดีกว่า
คือการใช้ตัวแปรสภาพ ดูมาตรา 18.6.1, หน้า 1003 สำหรับรายละเอียด
18.5.2 mutexes และล็อคในรายละเอียด
ในรายละเอียด mutexes
C + + มาตรฐานห้องสมุดให้ชั้นเรียนต่อไป mutex (ดูตาราง 18.6)
•มาตรฐานชั้น :: mutex เป็น mutex ง่ายๆที่สามารถ ถูกล็อคเพียงครั้งเดียวโดยหนึ่งด้ายในเวลา ถ้ามัน
ถูกล็อคล็อคอื่น ๆ () จะป้องกันจนกระทั่ง mutex สามารถใช้ได้อีกครั้งและ try_lock () จะ
ล้มเหลว
•คลาส std :: recursive_mutex เป็น mutex ที่ช่วยให้ล็อคหลายในเวลาเดียวกันโดย
หัวข้อเดียวกัน โปรแกรมทั่วไปเช่นล็อคเป็นที่ที่ฟังก์ชั่นได้รับการล็อคและ
ภายในเรียกใช้ฟังก์ชันอื่นซึ่งยังได้รับล็อคเดียวกันอีกครั้ง
การทำงาน recursive_ mutex
mutex
timed_mutex recursive_
timed_mutex
ล็อค () ซื้อกิจการ mutex (บล็อคถ้าไม่สามารถใช้ได้)
try_lock () ซื้อกิจการ mutex (กลับเท็จถ้าไม่สามารถใช้ได้)
ปลดล็อค () ปลดล็อค mutex
try_lock_for () - พยายามที่จะได้รับการล็อคสำหรับระยะเวลาของเวลา
try_lock_until () - พยายามที่จะได้รับการล็อคจน timepoint
หลายล็อคไม่ใช่
(หัวข้อเดียวกัน)
ไม่ ใช่
(หัวข้อเดียวกัน)
ตารางที่ 18.6 ภาพรวมของ mutexes และความสามารถของพวกเขา
www.it-ebooks.info
18.5 mutexes และล็อค 999
•คลาส std :: timed_mutex เป็น mutex ง่ายที่ยังช่วยให้คุณสามารถที่จะผ่านระยะเวลา
หรือ timepoint ที่กำหนดระยะเวลาที่จะพยายามที่จะได้รับการล็อค สำหรับนี้ try_lock_for () และ
try_lock_until () ไว้ให้
•มาตรฐานชั้น :: recursive_timed_mutex เป็น mutex ที่ช่วยให้หลายคนโดยล็อคเดียวกัน
ด้วยด้ายหมดเวลาตัวเลือก
ตารางที่ 18.7 รายการ mutex การดำเนินงานหากมี
การดำเนินการที่มีผล
สร้าง mutex เมตรเริ่มต้น ; สร้าง mutex ปลดล็อค
. เมตร ~ mutex () ทำลาย mutex (จะต้องไม่ถูกล็อค)
m.lock () ล็อค mutex (บล็อคล็อค; ข้อผิดพลาดถ้าล็อคและไม่
ซ้ำ)
m.try_lock () พยายามที่จะล็อค mutex (ผลตอบแทนจริงถ้าล็อคที่ประสบความสำเร็จ)
m.try_lock_for (Dur) พยายามที่จะล็อคสำหรับระยะเวลา Dur (ผลตอบแทนจริงถ้าล็อค
ที่ประสบความสำเร็จ)
m.try_lock_until (tp) พยายามที่จะล็อคจน timepoint tp (ผลตอบแทนจริงถ้าล็อค
ที่ประสบความสำเร็จ)
m.unlock () ปลดล็อค mutex (ถ้าไม่ได้กำหนดพฤติกรรมที่ไม่ได้ล็อค)
m.native_handle () ส่งกลับประเภท native_handle_type แพลตฟอร์มที่เฉพาะเจาะจงสำหรับ
การขยาย nonportable
ตารางที่ 18.7 การดำเนินงานของการเรียน Mutex ถ้ามี
การล็อค () อาจโยน std :: system_error (ดูมาตรา 4.3.1, หน้า 43) ที่มีข้อผิดพลาดดังต่อไปนี้
รหัส (ดูมาตรา 4.3.2, หน้า 45):
• operation_not_permitted ถ้าด้ายไม่ ไม่ได้มีสิทธิ์ที่จะดำเนินการ
• resource_deadlock_would_occur ถ้าแพลตฟอร์มตรวจพบว่าการหยุดชะงักจะเกิดขึ้น
• device_or_resource_busy ถ้า mutex ถูกล็อคอยู่แล้วและการป้องกันเป็นไปไม่ได้
การทำงานของโปรแกรมจะไม่ได้กำหนดว่าจะปลดล็อควัตถุ mutex มัน doesn ' เสื้อของตัวเองทำลาย mutex
วัตถุเจ้าของกระทู้ใด ๆ หรือถ้าด้ายสิ้นสุดลงในขณะที่การเป็นเจ้าของวัตถุ mutex
ทราบว่า try_lock_for () และ try_lock_until () มักจะแตกต่างกันเมื่อต้องรับมือกับ
การปรับเปลี่ยนระบบเวลา (ดูมาตรา 5.7.5, หน้า 160, สำหรับรายละเอียด)
lock_guard ชั้นในรายละเอียด
ของคลาส std :: lock_guard แนะนำในมาตรา 18.5.1, หน้า 989, มีอินเตอร์เฟซที่มีขนาดเล็กมากที่จะ
ให้แน่ใจว่าล็อค mutex ได้รับการปล่อยให้เป็นอิสระเสมอเมื่อออกจากขอบเขต (ดูตาราง 18.8) ตลอด
อายุการใช้งานของมันก็เป็นเรื่องที่เกี่ยวข้องเสมอกับล็อคอย่างใดอย่างหนึ่งได้รับการร้องขออย่างชัดเจนหรือนำไปใช้ในการก่อสร้าง
เวลา
www.it-ebooks.info
1000 บทที่ 18: Concurrency
ผลงาน
lock_guard แอลจี (ม. ) สร้างยามล็อคสำหรับ mutex เมตรและล็อค
lock_guard แอลจี (ม. , adopt_lock) สร้างยามล็อคสำหรับล็อค mutex เมตรแล้ว
แอลจี. ~ lock_guard () ปลด mutex และทำลายยามล็อค
ตารางที่ 18.8 การดำเนินงานของชั้น lock_guard
unique_lock ชั้นในรายละเอียด
ของคลาส std :: unique_lock แนะนำในมาตรา 18.5.1, หน้า 996 ให้ยามล็อคสำหรับ mutex
ที่ไม่จำเป็นต้องมีการถูกล็อค (เจ้าของ) มันมีอินเตอร์เฟซที่ระบุไว้ในตารางที่ 18.9
ถ้าล็อค / mutex เป็นเจ้าของในเวลาที่ถูกทำลายก็จะปลดล็อค () มัน แต่คุณสามารถควบคุมอย่างชัดเจน
ไม่ว่าจะมี mutex ที่เกี่ยวข้องและไม่ว่า mutex นี้ถูกล็อค นอกจากนี้คุณยังสามารถพยายามที่จะล็อค
mutex มีหรือไม่มีหมดเวลา
ล็อค () อาจโยน std :: system_error (ดูมาตรา 4.3.1, หน้า 43) ที่มีรหัสข้อผิดพลาด
ที่ระบุไว้สำหรับล็อค () เพื่อ mutexes (ดูหน้า 999) ปลดล็อค () อาจโยน std :: system_error ด้วย
รหัสข้อผิดพลาด operation_not_permitted ถ้าล็อคที่ไม่ซ้ำกันไม่ได้ล็อค
18.5.3 โทรเมื่อหลายหัวข้อใน
บางครั้งหลายหัวข้ออาจจะไม่ต้องมีการทำงานที่ควรจะได้รับการประมวลผลเมื่อใดก็ตามที่
หัวข้อแรกต้องการมัน . ตัวอย่างทั่วไปคือการเริ่มต้นขี้เกียจ: ครั้งแรกที่เป็นหนึ่งในหัวข้อที่
ต้องการสิ่งที่มีจะได้รับการประมวลผลที่คุณจะดำเนินการได้ (แต่ไม่ก่อนเพราะคุณต้องการที่จะประหยัด
เวลาในการประมวลผลมันถ้ามันไม่จำเป็นต้องใช้)
วิธีการตามปกติ ด้วยสภาพแวดล้อมที่เดียว threaded ง่าย: สัญญาณธงบูลีนไม่ว่าจะเป็น
ฟังก์ชั่นที่เรียกว่าแล้ว:
bool เริ่มต้น = false / / ธงทั่วโลก
...
ถ้า {/ / เริ่มต้นถ้าไม่ได้เริ่มต้นยัง (เริ่มต้น)
เริ่มต้น ();
เริ่มต้น = จริง;
}
หรือ
มาตรฐานคงที่ :: เวกเตอร์staticData;
foo โมฆะ ()
{
ถ้า (staticData.empty ()) {
staticData = initializeStaticData ();
}
...
}
www.it-ebooks.info
18.5 mutexes และล็อค 1001
ผลการดำเนินงาน
unique_lock ลิตรคอนสตรัคเริ่มต้น; สร้างล็อคไม่ได้ ที่เกี่ยวข้องกับ
mutex
ลิตร unique_lock (ม. ) สร้างยามล็อคสำหรับ mutex เมตรและล็อค
unique_lock ลิตร (ม. adopt_lock) สร้างยามล็อคสำหรับล็อค mutex เมตรแล้ว
ลิตร unique_lock (ม. , defer_lock) สร้างยามล็อคสำหรับ mutex เมตรโดยไม่ต้องล็อคมัน
ลิตร unique_lock (ม. , try_lock) สร้างยามล็อคสำหรับ mutex เมตรและพยายามที่จะล็อค
unique_lock ลิตร (ม. Dur) สร้างยามล็อคสำหรับ mutex เมตรและพยายามที่จะล็อคสำหรับ
ระยะเวลา Dur
unique_lock ลิตร (ม. , tp) สร้างยามล็อคสำหรับ mutex เมตรและพยายามที่จะล็อค
จน timepoint tp
ลิตร unique_lock (RV) ย้ายคอนสตรัค; ย้ายล็อครัฐจากรถอาร์วีที่ลิตร (RV ไม่มี
mutex ที่เกี่ยวข้องอีกต่อไป)
. ลิตร ~ unique_lock () ปลดล็อค mutex ถ้ามีล็อคและทำลายล็อค
ยาม
ลิตร unique_lock = มอบหมายย้าย RV; ย้ายรัฐล็อคจากรถอาร์วีที่ลิตร (รถอาร์วีมี
ไม่ mutex ที่เกี่ยวข้องอีกต่อไป)
การแลกเปลี่ยน (l1, l2) สวอปล็อค
l1.swap (l2) ล็อคแลกเปลี่ยน
l.release () ส่งตัวชี้ไปยัง mutex ที่เกี่ยวข้องและเผยแพร่มัน
l.owns_lock () คืนค่าจริงถ้า mutex ที่เกี่ยวข้องถูกล็อค
ถ้า (ลิตร) ตรวจสอบว่าเกี่ยวข้อง mutex ถูกล็อค
l.mutex () ส่งตัวชี้ไปยัง mutex ที่เกี่ยวข้อง
l.lock () ล็อค mutex ที่เกี่ยวข้อง
l.try_lock () พยายามที่จะล็อค mutex ที่เกี่ยวข้อง (ผลตอบแทนจริงถ้าล็อค
ที่ประสบความสำเร็จ)
l.try_lock_for (Dur) พยายามที่จะล็อค mutex ที่เกี่ยวข้องในช่วงระยะเวลา Dur (ผลตอบแทน
จริงถ้าล็อค ที่ประสบความสำเร็จ)
l.try_lock_until (tp) พยายามที่จะล็อค mutex ที่เกี่ยวข้องจน timepoint tp
(ผลตอบแทนจริงถ้าล็อคที่ประสบความสำเร็จ)
l.unlock () ปลด mutex เกี่ยวข้อง
ตารางที่ 18.9 การดำเนินงานของชั้น unique_lock
รหัสดังกล่าวไม่ทำงานในบริบทแบบมัลติเธรดเพราะการแข่งขันข้อมูลอาจเกิดขึ้นหากสองคนหรือมากกว่า
หัวข้อตรวจสอบว่าการเริ่มต้นไม่ได้เกิดขึ้นและยังเริ่มต้นการเริ่มต้นแล้ว ดังนั้นคุณ
ต้องปกป้องพื้นที่สำหรับการตรวจสอบและการเริ่มต้นกับการเข้าถึงพร้อมกัน
ตามปกติคุณสามารถใช้ mutexes สำหรับมัน แต่ C + + ห้องสมุดมาตรฐานให้วิธีพิเศษ
ในกรณีนี้ คุณก็ใช้มาตรฐาน :: once_flag และเรียก std :: call_once (ยังเป็นที่ที่ให้บริการโดย
):
std :: once_flag oc / / ธงทั่วโลก
...
std :: call_once (oc, เริ่มต้น) / / เริ่มต้นถ้ายังไม่ได้เริ่มต้น
www.it-ebooks.info
1002 บทที่ 18: Concurrency
หรือ:
มาตรฐานคงที่ :: เวกเตอร์staticData;
foo โมฆะ ()
{
มาตรฐานคงที่ :: once_flag oc;
std :: call_once (oc, [] {
staticData = initializeSt
การแปล กรุณารอสักครู่..
ผลลัพธ์ (ไทย) 3:[สำเนา]
คัดลอก!
18.5 mutexes และล็อค 997
ธง defer_lock สามารถ ตัวอย่างเช่น สามารถใช้ในการสร้างหนึ่งหรือหลายล็อคและล็อคพวกเขาในภายหลัง :
std : : mutex M1 ;
std : : mutex M2 ;
std : : unique_lock < std : : mutex > lockm1 ( M1 , std : : defer_lock ) ;
: : : unique_lock < std : : mutex > lockm2 ( m2 std : : defer_lock ) ;
.
std : : ล็อค ( M1 , M2 ) ; / / ล็อคทั้ง mutexes ( หรือไม่ถ้าไม่ที่สุด )
นอกจากนี้ชั้น unique_lock มีความสามารถในการ release() ของ mutex หรือโอนกรรมสิทธิ์
ของ mutex ล็อคอีก ดูส่วน 18.5.2 หน้า 1000 , รายละเอียด .
ทั้ง lock_guard และ unique_lock , ตอนนี้เราสามารถใช้เป็นตัวอย่างไร้เดียงสาที่
หัวข้อหนึ่ง รออีก โดยเลือกตั้งธงพร้อม :
#รวม < mutex >
. .
บูล readyflag ;
std : : mutex readyflagmutex ;

{ thread1() เป็นโมฆะ
/ / ทำ thread2 ต้องการการเตรียม
. .
: : : lock_guard < std : : mutex > LG ( readyflagmutex ) ;
readyflag = true ;
} {

เป็นโมฆะ thread2()
/ / รอจนกว่า readyflag เป็นจริง ( thread1 เสร็จ )
{
std : : unique_lock < std : : mutex > UL ( readyflagmutex ) ;
ในขณะที่ ! readyflag ) {
UL unlock() ;
: : : : : this_thread yield() ; / / คำใบ้เพื่อเลื่อนไปยังหัวข้อถัดไป this_thread STD
: : : : sleep_for ( std : : Chrono : : มิลลิวินาที ( 100 ) ;
UL lock() ;
}
} / / ปล่อยล็อค
/ / ทำสิ่งที่จะเกิดขึ้นหลังจาก thread1 ได้เตรียมสิ่งที่
.
}

www.it-ebooks ข้อมูล 1130 บทที่ 18 : การ
2 ความเห็นในคำถามโดยทั่วไปรหัสนี้จะเพิ่ม :
- ถ้าคุณสงสัยว่าทำไมเราใช้ mutex เพื่อควบคุมการเข้าถึง อ่านและเขียน readyflag
, จำกฎแนะนำจุดเริ่มต้นของบทนี้ : การเข้าถึง กับ ที่
อย่างน้อยหนึ่งเขียนควรจะตรงกัน ดูส่วน 18.4 หน้า ตัว และส่วนมากหน้า 1
, , สำหรับการอภิปรายรายละเอียดเกี่ยวกับเรื่องนี้ ถ้าคุณสงสัยว่า
- ไม่มีสารระเหยเป็นสิ่งจำเป็นที่นี่ เพื่อประกาศ readyflag หลีกเลี่ยงความพยายามหลาย
ใน thread2() อ่านจะไม่เหมาะไปทราบต่อไปนี้ : ความพยายามเหล่านี้

อ่าน readyflag เกิดขึ้นภายใน ส่วนวิกฤติระหว่างการตั้งค่าและการกำหนดของการล็อค เช่นรหัสไม่ได้รับอนุญาตที่จะได้รับที่ดีที่สุดในวิธีที่อ่าน ( หรือเขียน ) ย้าย
นอกส่วนที่สําคัญ ดังนั้น อ่าน readyflag ต้องมีประสิทธิภาพเกิดขึ้นที่นี่ :
) ที่จุดเริ่มต้นของลูป ระหว่างการประกาศของ UL และสายแรกของ unlock()
–ภายในวง ระหว่างใด ๆของ lock() unlock()
และเรียกและที่ส่วนท้ายของลูป ระหว่างสายของ lock() และการทําลายของ UL ซึ่ง

แต่ถ้าปลดล็อค mutex เช่นโพลล์เพื่อเติมเต็มเงื่อนไขมักจะไม่ได้เป็นทางออกที่ดี a
วิธีการที่ดีกว่าคือการใช้ตัวแปรสภาวะ ดูส่วน 18.6.1 หน้า 1002 , รายละเอียด .
18.5.2 mutexes และล็อคในรายละเอียด

mutexes ในรายละเอียดมาตรฐาน c ห้องสมุดให้ mutex ชั้นเรียนต่อไปนี้ ( ดูจากตาราง 18.6 ) :
- คลาส std : : mutex เป็น mutex อย่างง่ายที่สามารถล็อกได้เพียงครั้งเดียว โดยหัวข้อหนึ่งในเวลา ถ้ามัน
ล็อค อื่น ๆ lock() จะปิดกั้นจน mutex สามารถใช้ได้อีกครั้ง และ try_lock()

- จะล้มเหลว คลาส std : : recursive_mutex เป็น mutex ที่ช่วยล็อคหลายในเวลาเดียวกันโดย
หัวข้อเดียวกันการประยุกต์ใช้โดยทั่วไป เช่น ล็อคที่ล็อคและฟังก์ชั่นได้รับ
ภายในเรียกฟังก์ชั่นอื่น ซึ่งยัง มีล็อคกันอีกครั้ง งาน mutex recursive_




mutex timed_mutex recursive_ timed_mutex lock() ได้มา mutex ( บล็อกถ้าไม่พร้อม )
try_lock() ได้มา mutex ( ส่งกลับเท็จถ้าไม่พร้อม )
unlock() ปลดล็อค mutex
try_lock_for() ––พยายามที่จะได้รับล็อคสำหรับระยะเวลาของเวลา
try_lock_until() ––พยายามที่จะได้รับล็อคจน timepoint

( หลายล็อค ไม่ ใช่ ไม่ ใช่ หัวข้อเดียวกัน )

( หัวข้อเดียวกัน )
โต๊ะขนาดใหญ่ . ภาพรวมของ mutexes และความสามารถ

www.it-ebooks ข้อมูล 18.5 mutexes และล็อค 999
- คลาส std : : timed_mutex เป็นง่าย mutex ที่ยังช่วยให้คุณผ่านช่วงเวลา
หรือ timepoint ที่กําหนดระยะเวลาที่พยายามที่จะได้รับล็อค สำหรับเรื่องนี้ try_lock_for() และ

try_lock_until() ที่มีให้บริการห้อง std : : recursive_timed_mutex เป็น mutex ที่ช่วยล็อคหลายเธรดเดียวกัน

กับหมดเวลาก็ได้ ตารางราคารายการ mutex การดําเนินงาน ถ้าใช้ได้ผล
.
งาน mutex M เริ่มต้นผู้สร้าง สร้างปลดล็อค mutex
M~ mutex() ทำลาย mutex ( ไม่ต้องล็อค )
. lock() ล็อค mutex ( บล็อกสำหรับล็อค ข้อผิดพลาด ถ้าล็อคไม่ได้

) try_lock() recursive ) พยายามที่จะล็อค mutex ( ผลตอบแทนจริงถ้าล็อคสำเร็จ )
m.try_lock_for ( เหล็ก ) พยายามที่จะล็อคตลอดช่วง ( ผลตอบแทนจริงถ้าล็อค
ประสบความสำเร็จ )
m.try_lock_until ( TP ) พยายามที่จะล็อคจนกว่า timepoint TP ( ผลตอบแทนจริงถ้าล็อค
ความสำเร็จ
Munlock() ปลด mutex ( ไม่ได้กำหนดพฤติกรรม ถ้าไม่ได้ล็อค )
. native_handle() ส่งกลับเป็นแพลตฟอร์มสำหรับชนิดที่เฉพาะเจาะจง native_handle_type

nonportable ส่วนขยายตารางราคา . การดำเนินงานของ mutex ชั้นเรียน ถ้าใช้ได้
lock() อาจโยน std : : system_error ( ดูส่วนใน , หน้า 43 ) กับรหัสข้อผิดพลาด
ต่อไปนี้ ( ดูมาตรา 4.3.2 , หน้า 45 ) :
operation_not_permitted - ,ถ้าด้ายไม่มีสิทธิ์ที่จะดำเนินการได้
- resource_deadlock_would_occur ถ้าตรวจพบว่าแพลตฟอร์มการหยุดชะงักจะเกิดขึ้น
- device_or_resource_busy ถ้า mutex แล้วล็อกและบล็อกเป็นไปไม่ได้
พฤติกรรมของโปรแกรมเป็นภาษาอังกฤษถ้ามันปลดล็อค mutex วัตถุมันไม่ได้เอง ทําลาย mutex
วัตถุ เป็นเจ้าของโดยด้ายหรือถ้าด้ายสิ้นสุดลงในขณะที่ owning mutex วัตถุ .
ทราบว่า try_lock_for() try_lock_until() และมักจะแตกต่างกัน เมื่อจัดการกับการปรับเปลี่ยนเวลาของระบบ ( ดูที่ส่วน
5.7.5 , หน้า 160 , สำหรับรายละเอียด )
lock_guard ในคลาสเรียน รหัส STD
: : lock_guard แนะนำในส่วน 18.5.1 หน้า , 989 , มีอินเตอร์เฟซที่มีขนาดเล็กมาก

ให้แน่ใจว่าล็อค mutex ได้รับเสมออิสระเมื่อออกจากขอบเขต ( ดูจากตารางร้อย ) ตลอด
อายุการใช้งานของมันก็มักจะเกี่ยวข้องกับล็อคอย่างใดอย่างหนึ่งชัดเจนหรือลูกบุญธรรมที่ร้องขอเวลาก่อสร้าง
.
www.it-ebooks ข้อมูล
1000 บทที่ 18 : การดำเนินงานผล

lock_guard LG ( M ) สร้างล็อคการ์ดสำหรับ mutex M และล็อคมัน
lock_guard LG ( Madopt_lock ) สร้างล็อคยามแล้วล็อค mutex M
LG ~ lock_guard() ปลด mutex และทำลายล็อคยาม
โต๊ะญี่ปุ่น . การดำเนินงานของคลาสเรียนในชั้นเรียน unique_lock lock_guard

: : รายละเอียด : unique_lock แนะนำในส่วน 18.5.1 หน้า , 996 , มีล็อคป้องกันสำหรับ mutex
ที่ไม่จําเป็นต้องล็อค ( เป็นเจ้าของ ) มันมีอินเตอร์เฟซที่แสดงในตารางที่ 18.9 .
ถ้ามันล็อค / เจ้าของ mutex เวลาทำลาย มันก็จะ unlock() . แต่คุณสามารถควบคุมอย่างชัดเจน
ไม่ว่าจะมีความเกี่ยวข้อง mutex และไม่ว่า mutex นี้ถูกล็อค นอกจากนี้คุณยังสามารถพยายามที่จะล็อค
mutex ที่มีหรือไม่มีหมดเวลา .
lock() อาจโยน std : : system_error ( ดูส่วนใน , หน้า 43 ) กับรหัสข้อผิดพลาด
ไว้ lock() สำหรับ mutexes ( ดูหน้า 999 ) unlock() อาจโยน std : :system_error กับ
รหัสข้อผิดพลาด operation_not_permitted ถ้ามันล็อคเฉพาะไม่ล็อก 18.5.3 โทรมาครั้งนึงหลายกระทู้

บางครั้งหลายๆ กระทู้ อาจจะไม่ต้องมีฟังก์ชันการทำงานที่ควรจะดำเนินการเมื่อ
หัวข้อแรกต้องการ ตัวอย่างทั่วไปคือเริ่มขี้เกียจ : ครั้งแรกหนึ่งในกระทู้
ต้องการบางอย่างที่ได้รับการประมวลผลคุณจัดการมัน ( แต่ไม่ก่อน เพราะคุณต้องการบันทึก
เวลาประมวลผลถ้าไม่จําเป็น ) .
วิธีปกติกับเดี่ยวเธรดสภาพแวดล้อมที่ง่าย : ตรรกะธงสัญญาณว่าฟังก์ชันถูกเรียกแล้ว

บูลเริ่มต้น = false ; / / โลกธง

ถ้า ( . . . . . . . ! เริ่มต้น ) { / / เริ่มใช้งาน ถ้าไม่เริ่มต้นเลย

initialize() ; เริ่มต้น = true ;
}

คง std : : หรือเวกเตอร์สาย > < std : : staticdata ;


ถ้าเป็นโมฆะ foo() { ( staticdata . empty() ) {

} staticdata = initializestaticdata() ;
.
}

www.it-ebooks ข้อมูล 18.5 mutexes และล็อค 1001

งานผล unique_lock ผมเริ่มต้นสร้าง ; สร้างล็อคไม่ได้เกี่ยวข้องกับ mutex

unique_lock l ( M ) สร้างล็อคการ์ดสำหรับ mutex M และล็อคมัน
unique_lock L ( Madopt_lock ) สร้างล็อคยามแล้วล็อค mutex M
unique_lock L ( M , defer_lock ) สร้างล็อคการ์ดสำหรับ mutex ม. โดยไม่ต้องล็อคมัน
unique_lock L ( M , try_lock ) สร้างล็อคการ์ดสำหรับ mutex M และพยายามที่จะล็อค
unique_lock L ( M น่ะ ) สร้างล็อคยาม สำหรับ mutex M และพยายามที่จะล็อคสำหรับระยะเวลาน่ะ

unique_lock L ( MTP ) สร้างล็อคการ์ดสำหรับ mutex M และพยายามที่จะล็อค timepoint TP

จน unique_lock L ( RV ) ย้ายผู้รับเหมาก่อสร้าง ; ย้ายล็อคสถานะจาก L ( RV RV ไม่มี
เกี่ยวข้อง mutex อีกแล้ว )
. ~ unique_lock() ปลด mutex ถ้ามีการล็อคและทำลายล็อค

unique_lock ยาม L = RV งานเลื่อน เลื่อนล็อคสถานะจาก RV L ( RV มีไม่ที่เกี่ยวข้อง mutex อีกแล้ว

) สลับ ( L1 , L2 ) การล็อค
l1 .( 2 ) แลกเปลี่ยนสลับล็อค
L release() กลับชี้ไปที่เกี่ยวข้อง mutex และออก
L owns_lock() ผลตอบแทนจริงถ้าเกี่ยวข้อง mutex ล็อค
ถ้า ( ผม ) จะตรวจสอบว่ามีความเกี่ยวข้อง mutex ล็อค
L mutex() กลับชี้ไปที่เกี่ยวข้อง mutex
L lock() ล็อคที่เกี่ยวข้อง mutex
L try_lock() พยายาม ล็อคที่เกี่ยวข้อง mutex ( ผลตอบแทนจริงถ้าล็อค
ความสำเร็จ
Ltry_lock_for ( เหล็ก ) พยายามที่จะล็อคที่เกี่ยวข้อง mutex ตลอดช่วง ( ผลตอบแทนจริงถ้าล็อคประสบความสำเร็จ

) l.try_lock_until ( TP ) พยายามที่จะล็อคที่เกี่ยวข้อง mutex จนกว่า timepoint TP
( ผลตอบแทนจริงถ้าล็อคสำเร็จ )
. unlock() ปลดล็อคที่เกี่ยวข้อง mutex
โต๊ะที่สูง . การดำเนินงานของคลาส unique_lock
เช่นรหัสไม่ได้ทำงานในแบบมัลติเธรดบริบท เพราะการแข่งขันข้อมูลที่อาจจะเกิดขึ้น ถ้าสองคนหรือมากกว่า
หัวข้อตรวจสอบว่าเริ่มต้นที่ไม่ได้เกิดขึ้นและยังเริ่มการเริ่มต้นแล้ว ดังนั้น คุณ
ต้องปกป้องพื้นที่เพื่อตรวจสอบและการเริ่มต้นกับการเข้าถึงพร้อมกัน
ตามปกติ คุณสามารถใช้ mutexes สำหรับมัน แต่มาตรฐานห้องสมุดให้
โซลูชั่นพิเศษ สำหรับคดีนี้ คุณเพียงแค่ใช้ std : : once_flag เรียก std : : call_once ( โดย mutex
< >
) : : : :once_flag OC ; / / โลกธง
. .
: : : call_once ( OC เริ่มต้น ) ; / / เริ่มใช้งาน ถ้าไม่เริ่มต้นเลย

www.it-ebooks ข้อมูล 1002 บทที่ 18 : การเห็นพ้องด้วย

คง STD หรือ : : : > < : : : > staticdata สตริงโมฆะ {

;
foo() สถิต std : : once_flag OC ;
std : : call_once ( OC [ ] {
staticdata = initializest
การแปล กรุณารอสักครู่..
 
ภาษาอื่น ๆ
การสนับสนุนเครื่องมือแปลภาษา: กรีก, กันนาดา, กาลิเชียน, คลิงออน, คอร์สิกา, คาซัค, คาตาลัน, คินยารวันดา, คีร์กิซ, คุชราต, จอร์เจีย, จีน, จีนดั้งเดิม, ชวา, ชิเชวา, ซามัว, ซีบัวโน, ซุนดา, ซูลู, ญี่ปุ่น, ดัตช์, ตรวจหาภาษา, ตุรกี, ทมิฬ, ทาจิก, ทาทาร์, นอร์เวย์, บอสเนีย, บัลแกเรีย, บาสก์, ปัญจาป, ฝรั่งเศส, พาชตู, ฟริเชียน, ฟินแลนด์, ฟิลิปปินส์, ภาษาอินโดนีเซี, มองโกเลีย, มัลทีส, มาซีโดเนีย, มาราฐี, มาลากาซี, มาลายาลัม, มาเลย์, ม้ง, ยิดดิช, ยูเครน, รัสเซีย, ละติน, ลักเซมเบิร์ก, ลัตเวีย, ลาว, ลิทัวเนีย, สวาฮิลี, สวีเดน, สิงหล, สินธี, สเปน, สโลวัก, สโลวีเนีย, อังกฤษ, อัมฮาริก, อาร์เซอร์ไบจัน, อาร์เมเนีย, อาหรับ, อิกโบ, อิตาลี, อุยกูร์, อุสเบกิสถาน, อูรดู, ฮังการี, ฮัวซา, ฮาวาย, ฮินดี, ฮีบรู, เกลิกสกอต, เกาหลี, เขมร, เคิร์ด, เช็ก, เซอร์เบียน, เซโซโท, เดนมาร์ก, เตลูกู, เติร์กเมน, เนปาล, เบงกอล, เบลารุส, เปอร์เซีย, เมารี, เมียนมา (พม่า), เยอรมัน, เวลส์, เวียดนาม, เอสเปอแรนโต, เอสโทเนีย, เฮติครีโอล, แอฟริกา, แอลเบเนีย, โคซา, โครเอเชีย, โชนา, โซมาลี, โปรตุเกส, โปแลนด์, โยรูบา, โรมาเนีย, โอเดีย (โอริยา), ไทย, ไอซ์แลนด์, ไอร์แลนด์, การแปลภาษา.

Copyright ©2024 I Love Translation. All reserved.

E-mail: