18.1 ระดับสูง Interface: async () และฟิวเจอร์ส 961
}
กลับ NUM;
}
doSomething โมฆะ (ถ่าน C, shared_futureฉ)
{
try {
/ / รอจำนวนตัวอักษรที่จะพิมพ์
NUM int = f.get () / / ได้รับผลจากการ queryNumber ()
for (int i = 0; ฉันthis_thread :: sleep_for (โครโนกราฟ :: มิลลิวินาที (100));
. cout.put (c) ล้าง ();
}
}
catch (ยกเว้น const และ e) {
cerr << "ข้อยกเว้นในหัวข้อ" << this_thread :: get_id ()
<< ":" << e.what () << endl;
}
}
int หลัก ()
{
try {
/ / เริ่มต้นหนึ่งด้ายเพื่อสอบถามจำนวน
shared_futuref = async (queryNumber);
/ / เริ่มต้นสามหัวข้อการประมวลผลแต่ละจำนวนนี้ในวง
async f1 อัตโนมัติ = (การเปิดตัว :: async, doSomething, ฉ '.');
f2 รถยนต์ = async (เปิดตัว :: async, doSomething, '+', ฉ);
f3 รถยนต์ = async (เปิดตัว :: async, doSomething, '*', ฉ);
/ / รอลูปทั้งหมดจะแล้วเสร็จ
f1.get ();
f2.get ();
f3.get ();
}
catch (ยกเว้น const และ e) {
ศาล << " nEXCEPTION:" << e.what () << endl;
}
ศาล << " ndone" << endl;
}
www.it-ebooks.info
962 บทที่ 18: Concurrency
ในตัวอย่างนี้ด้ายเรียก queryNumber () เพื่อสอบถามค่าหนึ่งซึ่งถูกนำมาใช้แล้วโดย
หัวข้ออื่น ๆ ทำงานอยู่แล้ว การดำเนินการนี้เป็นผลมาจากมาตรฐาน :: async () ซึ่งจะเริ่มต้น
ด้ายแบบสอบถามได้รับมอบหมายให้เป็นวัตถุ shared_future, พิเศษสำหรับค่าตอบแทน:
shared_futureฉ async = (queryNumber);
ดังนั้นในอนาคตที่ใช้ร่วมกันสามารถเริ่มต้นได้โดยในอนาคตสามัญซึ่งย้ายจากรัฐ
ในอนาคตที่จะใช้ร่วมกันในอนาคต เพื่อให้สามารถใช้รถยนต์สำหรับการประกาศนี้คุณสามารถผลัดกันใช้
ร่วมกัน () ฟังก์ชันสมาชิก:
. รถยนต์ f = async (queryNumber) หุ้น ();
ภายในวัตถุที่ใช้ร่วมกันทั้งหมดในอนาคตร่วมกันของรัฐที่ใช้ร่วมกันซึ่ง async () สร้างเพื่อเก็บผล
ของการทำงานที่ผ่านมา (และการจัดเก็บฟังก์ชั่นของตัวเองหากมีการเลื่อนเวลาออกไป)
ในอนาคตที่ใช้ร่วมกันจะถูกส่งไปยังหัวข้ออื่น ๆ เริ่มต้น doSomething () ที่มีการใช้ร่วมกัน
ในอนาคตเป็นอาร์กิวเมนต์ที่สอง:
f1 = async อัตโนมัติ (การเปิดตัว :: async, doSomething, ฉ) '.';
f2 รถยนต์ = async (เปิดตัว :: async, doSomething, '+', ฉ);
f3 รถยนต์ = async (เปิดตัว :: async, doSomething, '*', ฉ) ;
ภายในแต่ละสายของ doSomething () เรารอผลและประมวลผลของ queryNumber () โดยการเรียก
รับ () สำหรับอนาคตที่ใช้ร่วมกันผ่าน:
doSomething โมฆะ (ถ่าน C, shared_futureฉ)
{
try {
NUM int = f.get () / / ได้รับผลจากการ queryNumber ()
...
}
catch (ยกเว้น const และ e) {
cerr << "ข้อยกเว้นในหัวข้อ" << this_thread :: get_id ()
< <":" << e.what () << endl;
}
}
หาก queryNumber () พ่นข้อยกเว้นที่เกิดขึ้นถ้าไม่มีค่าหนึ่งสามารถอ่านแต่ละ
สายของ doSomething () จะได้รับการยกเว้นนี้กับ f.get ( ) เพื่อให้ข้อยกเว้นที่สอดคล้องกัน
ในการจัดการที่จะเกิดขึ้น
ดังนั้นหลังจากที่ได้อ่านค่า 5 เป็นอินพุทเอาท์พุทอาจจะ:
จำนวนอ่าน: 5
. * + * + * + * + * +....
ทำ
แต่ถ้าพิมพ์ ' x 'เป็นนำเข้าส่งออกอาจจะ:
จำนวนอ่าน: x
ข้อยกเว้นในหัวข้อที่ 3: จำนวนไม่อ่าน
ข้อยกเว้นในหัวข้อที่ 4: ไม่มีเลขอ่าน
ข้อยกเว้นในหัวข้อที่ 2: จำนวนไม่อ่าน
ทำ
www.it-ebooks.info
18.1 สูง การเชื่อมต่อระดับ: async () และฟิวเจอร์ส 963
ทราบว่าคำสั่งของออกด้ายและค่า ID ที่ไม่ได้กำหนด (ดูมาตรา 18.2.1,
หน้า 967 สำหรับรายละเอียดเกี่ยวกับรหัสด้าย)
นอกจากนี้ยังทราบว่ามีความแตกต่างเล็กน้อยใน ประกาศรับ () ระหว่างในอนาคตและ
shared_future:
•สำหรับอนาคตการเรียน <> รับ () จะให้ดังต่อไปนี้ (T เป็นชนิดของค่ากลับ):
T อนาคต:: ได้รับ () / / รับทั่วไป ()
T & อนาคต:: ได้รับ () / / ความเชี่ยวชาญสำหรับการอ้างอิงใน
อนาคตเป็นโมฆะ:: ได้รับ () / / ความเชี่ยวชาญในการเป็นโมฆะ
ที่รูปแบบแรกจะส่งกลับผลการย้ายหรือสำเนาของผล
•สำหรับ shared_future ชั้น <> รับ () จะให้ดังต่อไปนี้
const T & shared_future:: ได้รับ () / / รับทั่วไป ()
T & shared_future:: ได้รับ () / / ความเชี่ยวชาญสำหรับการอ้างอิง
shared_future โมฆะ:: ได้รับ () / / ความเชี่ยวชาญในการเป็นโมฆะ
รูปแบบครั้งแรกที่ผลตอบแทนอ้างอิงกับค่าผลที่เก็บไว้ในสภาพที่ใช้ร่วมกันที่ใช้ร่วมกัน
หรือเป็น [N3194: ฟิวเจอร์ส] ฯ :
"ค่าใช้ครั้งเดียวจะได้รับ () เป็นย้าย ที่ดีที่สุด (เช่นมาตรฐาน :: เวกเตอร์v = f.get ()) ...
ได้รับการอ้างอิง const () คือการเข้าถึงที่ดีที่สุด (เช่น int i = f.get () [3]). "
การออกแบบนี้จะแนะนำความเสี่ยงของอายุการใช้งานหรือปัญหาการแข่งขันข้อมูลถ้าค่ากลับมาได้รับการแก้ไข (ดู
มาตรา 18.3 3, หน้า 977, สำหรับรายละเอียด)
นอกจากนี้คุณยังสามารถผ่านในอนาคตร่วมกันโดยการอ้างอิง (นั่นคือประกาศเป็นข้อมูลอ้างอิงและใช้
std :: อ้างอิง () ที่จะผ่านมัน):
doSomething โมฆะ (ถ่าน C, const shared_futureและฉ)
f1 รถยนต์ = async (เปิดตัว :: async, doSomething, std :: อ้างอิง (ฉ '.'));
ตอนนี้แทนการใช้ในอนาคตที่ใช้ร่วมกันหลายวัตถุทั้งหมดที่ใช้ร่วมกันรัฐเดียวกันคุณต้องการใช้อย่างใดอย่างหนึ่ง
ที่ใช้ร่วมกัน วัตถุในอนาคตที่จะดำเนินการได้รับหลาย () 's (หนึ่งในแต่ละหัวข้อ) แต่วิธีนี้มี
ความเสี่ยงมากขึ้น เป็นโปรแกรมเมอร์ที่คุณต้องให้แน่ใจว่าอายุการใช้งานของ f (ใช่ฉ, รัฐไม่ได้ใช้ร่วมกัน
มันหมายถึง) ไม่ได้มีขนาดเล็กกว่าสำหรับหัวข้อเริ่มต้น นอกจากนี้ทราบว่าฟังก์ชั่นสมาชิกของ
ฟิวเจอร์สที่ใช้ร่วมกันไม่ได้ประสานกับตัวเองแม้ว่ารัฐที่ใช้ร่วมกันที่ใช้ร่วมกันจะตรง
ดังนั้นถ้าคุณทำมากขึ้นกว่าเพียงแค่การอ่านข้อมูลที่คุณอาจจำเป็นต้องใช้เทคนิคการประสานภายนอก (ดูมาตรา
18.4, หน้า 982) เพื่อหลีกเลี่ยงการแข่งขันข้อมูลซึ่งจะส่งผลให้เกิดพฤติกรรมที่ไม่ได้กำหนด หรือเป็นอเรนซ์
Crowl หนึ่งในผู้เขียนของห้องสมุดพร้อมกันเขียนไว้ในการสื่อสารส่วนตัว: "ถ้ารหัส
อยู่ที่การประสานงานแน่นผ่านโดยการอ้างอิงจะปรับ ถ้ารหัสเผยแพร่อาจเป็นภูมิภาคที่มี
ความเข้าใจที่ไม่สมบูรณ์ของวัตถุประสงค์และข้อ จำกัด ในการผ่านโดยค่าจะดีกว่า การคัดลอก
ในอนาคตที่ใช้ร่วมกันมีราคาแพง แต่ไม่แพงเพื่อที่จะแสดงให้เห็นถึงข้อผิดพลาดที่แฝงอยู่ในระบบขนาดใหญ่ ".
สำหรับรายละเอียดเพิ่มเติมของ shared_future ชั้นดูส่วน 18.3.3, หน้า 976
www.it-ebooks.info
964 บทที่ 18: Concurrency
18.2 การเชื่อมต่อระดับต่ำ-: กระทู้และสัญญา
นอกจากนี้อินเตอร์เฟซระดับสูงของ async () และ (ใช้ร่วมกัน) ฟิวเจอร์ส C + + ห้องสมุดมาตรฐานให้
อินเตอร์เฟซในระดับต่ำที่จะเริ่มกระทู้และจัดการกับพวกเขา
18.2.1 มาตรฐานประเภท: : ด้าย
ด้ายในการเริ่มต้นคุณก็ต้องประกาศวัตถุของมาตรฐานชั้น :: ด้ายและผ่านที่ต้องการ
งานที่เป็นอาร์กิวเมนต์เริ่มต้นและแล้วทั้งรอสิ้นหรือถอดมัน
doSomething โมฆะ ();
std :: ด้ายที (doSomething) / / เริ่มต้น doSomething () ในพื้นหลัง
...
t.join () / / รอทีให้เสร็จ (บล็อกจน doSomething () สิ้นสุด)
สำหรับ async () คุณสามารถส่งผ่านสิ่งที่เป็น callable วัตถุ (ฟังก์ชั่นการทำงานของสมาชิกฟังก์ชัน
วัตถุแลมบ์ดา; ดูหัวข้อ 4.4, หน้า 54) ร่วมกับข้อโต้แย้งที่เป็นไปได้เพิ่มเติม แต่
ทราบอีกครั้งว่าถ้าคุณไม่ทราบจริงๆสิ่งที่คุณกำลังทำคุณควรจะผ่านวัตถุทั้งหมดที่จำเป็นในการ
ประมวลผลการทำงานที่ผ่านค่าด้ายเพื่อให้ใช้เพียงสำเนาท้องถิ่น (ดูมาตรา 18.4,
หน้า 982, สำหรับบางส่วนของปัญหาที่อาจจะ เกิดขึ้นเป็นอย่างอื่น)
นอกจากนี้เป็นอินเตอร์เฟซในระดับต่ำดังนั้นสิ่งที่น่าสนใจคือสิ่งที่อินเตอร์เฟซนี้จะไม่
ให้เมื่อเทียบกับ async () (ดูมาตรา 18.1, หน้า 946):
•ด้ายชั้นไม่ได้มีการเปิดตัวนโยบาย . C + + ห้องสมุดมาตรฐานมักจะพยายามที่จะเริ่มต้น
การทำงานที่ผ่านมาในหัวข้อใหม่ ถ้าเป็นไปไม่ได้ที่มันจะพ่น std :: system_error (ดู
มาตรา 4.3.1, หน้า 43) ด้วย resource_unavailable_try_again รหัสข้อผิดพลาด (ดูมาตรา
4.3.2, หน้า 45)
•คุณมีอินเตอร์เฟซที่ไม่มีผลในการประมวลผลหรือ ผลของด้าย สิ่งเดียวที่คุณจะได้รับ
คือรหัสกระทู้ที่ไม่ซ้ำกัน (ดูมาตรา 18.2.1, หน้า 967)
•หากเกิดข้อยกเว้นที่ไม่ได้ติดอยู่ภายในด้ายโปรแกรมที่ถูกยกเลิกทันทีเรียก
std :: ยุติ () (ดูมาตรา 5.8.2, หน้า 162) ที่จะผ่านข้อยกเว้นกับบริบทภายนอก
exception_ptrs ด้าย (ดูมาตรา 4.3.3, หน้า 52) จะต้องถูกนำมาใช้
•คุณต้องประกาศว่าเป็นโทร, คุณต้องการที่จะรอปลายด้าย (โทร
เข้าร่วม ( )) หรือแยกออกจากด้ายเริ่มที่จะปล่อยให้มันทำงานในพื้นหลังโดยไม่มีการควบคุมใด ๆ
(เรียกแยก ()) ถ้าคุณไม่ทำเช่นนี้ก่อนที่จะอายุของวัตถุด้ายสิ้นสุดลงหรือย้าย
มอบหมายให้มันเกิดขึ้นโปรแกรมถูกยกเลิกเรียก std :: ยุติ () (ดูมาตรา 5.8.2,
หน้า 162)
•หากคุณปล่อยให้ ใช้ด้ายในพื้นหลังและหลัก () สิ้นสุดลงหัวข้อทั้งหมดจะถูกยกเลิกทันที
นี่คือตัวอย่างที่สมบูรณ์เป็นครั้งแรก:
/ / concurrency/thread1.cpp
# include
# include
www.it-ebooks.info
การแปล กรุณารอสักครู่..
