Tag Archives: NSOperationQueue

Objective-C Programming Chapter 19 (Part2)

NSOperation

NSOperation นี้เปรียบเสมือนหนึ่งหน่วยของการทำงาน แต่เนื่องจากคลาส NSOperation เป็น abstract class ดังนั้นจึงไม่สามารถใช้คลาสนี้ได้โดยตรง ต้องประกาศซับคลาสขึ้นมาใช้งาน หรืออาจจะใช้ซับคลาสของระบบ เช่น NSBlockOperation หรือ NSInvocationOperation ได้เช่นเดียวกัน จุดประสงค์หลักของคลาสนี้คือเตรียมฟังชั่นการทำงานบางอย่างที่จำเป็นของ task ไว้ให้ เช่น กำหนดลำดับความสำคัญ และบอกสถานะการทำงาน ซึ่งมีด้วยกันทั้งหมด 4 สถานะคือ ready, executing, finish และ cancel  อ็อบเจ็กของคลาสนี้มีลักษณะเป็นแบบ single-shot นั่นคือ ทำงานได้ครั้งเดียว เมื่อให้ทำงานไปแล้วโอเปอร์เรชันจะไม่สามารถนำกลับมาใช้ได้อีก

NSInvocationOperation

NSInvocationOperation เป็นซับคลาสของ NSOperation มีจุดประสงค์เพื่อใช้กับเมธอดของอ็อบเจ็ก ดังนั้นการประกาศอ็อบเจ็กของคลาสนี้ต้องกำหนด selector พร้อมกับอ็อบเจ็กที่ต้องการให้ทำงาน เช่นตัวอย่าง โปรแกรมต่อไปนี้

Program 19.5

NetworkController.h

NetworkController.m

จากโค้ดตัวอย่าง เมธอด downloadWithURL: นั้นทำหน้าที่เพียงแค่สร้าง operation object และได้กำหนด selector เป็น performDownload: ซึ่งเป็นเมธอดที่ใช้สำหรับดาวน์โหลดข้อมูล เมื่อโอเปอร์เรชันทำงานก็จะเรียกใช้เมธอดนี้นั่นเอง Continue reading Objective-C Programming Chapter 19 (Part2)

Objective-C Programming Chapter 19 (Part1)

Grand Central Dispatch

 

ทุกวันนี้เทคโนโลยีของ CPU ได้ก้าวหน้าไปมาก จากแต่เดิมที่มุ่งเน้นการเพิ่มความเร็วของสัญญานาฬิกา ได้เปลี่ยนมาเป็นเพิ่มจำนวนแกนของ CPU หรือที่เรียกว่า multicore แต่การที่จะใช้ซีพียูให้เกิดประสิทธิภาพสูงที่สุดนั้น โปรแกรมจำเป็นต้องสามารถทำงานได้หลายอย่างพร้อมกันได้ ในอดีตการที่โปรแกรมที่ใช้ซีพียูแบบ multiple core นั้นจะมีการสร้าง thread หลายๆตัวเพื่อให้แต่ละ thread ได้ใช้แกนของซีพียูได้หลายแกนพร้อมกัน แต่อย่างไรก็ตามปัญหาที่ตามมาก็คือการเพิ่มจำนวน thread นั้นในบางครั้ง ไม่ได้ช่วยให้เกิดประสิทธิภาพมากขึ้น เพราะเมื่อถึงจุดหนึ่งจำนวนของเทรดจะมีผลต่อประสิทธิภาพของโปรแกรม ดังนั้นโปรแกรมเมอร์จึงต้องหาจุดที่จำนวนเทรดเหมาะสมพอดีกับซีพียู ไม่มากไปหรือไม่น้อยไป และถึงแม้ว่าจะหาจำนวนของเทรดที่พอดีได้แล้วก็ได้ตาม ก็ยังเป็นเรื่องยากที่จะต้องจัดการแต่ละ thread ไม่ให้ขัดขวางการทำงานซึ่งกันและกัน เพื่อแก้ปัญหาต่างๆเหล่านี้ Apple จึงได้สร้างเทคโนโลยีใหม่ขึ้นมาที่เรียกว่า Grand Central Dispatch ( GCD ) ซึ่งเป็นเทคโนโลยีใหม่ ที่ได้นำมาใช้กับระบบปฎิบัติการ Mac OS X และ iOS เพื่อจัดการปัญหาเหล่านี้
เทคนิคการทำงานเบื้องหลังของ GDC คือ Asynchronous Function ที่ได้อธิบายไปแล้วในบทก่อนว่า เป็นการทำงานแบบอนุญาติให้ฟังชั่นอื่นเริ่มทำงานได้ทันที โดยต้องไม่ต้องรอให้ฟังชั่นที่กำลังทำงานในปัจจุบันเสร็จสิ้นเสียก่อน แม้ว่าเทคนิคการทำงานแบบนี้มีมานานแล้ว แต่โปรแกรมเมอร์ต้องเป็นคนเขียนโค้ด asynchronous function เองรวมไปถึงสร้าง thread ที่ใช้ทำงานร่วมกับฟังชั่นด้วยตัวเองทั้งหมด แต่หลังจากที่มีเทคโนโลยี GCD เข้ามา งานของโปรแกรมเมอร์ก็ลดน้อยลงเพราะไม่ต้องเขียนโครงสร้างการทำงานแบบ asynchronous function และโค้ดที่ใช้สร้างและจัดการ thread สิ่งที่โปรแกรมเมอร์ต้องทำจะเหลือแต่เพียงแค่การเขียนโค้ดของงานที่ต้องทำจริงๆ จากนั้นหลังจากนั้นก็ส่งต่อเข้าไปยัง dispatch queue ที่เหลือจะเป็นหน้าที่ของ GCD ที่จะจัดการสร้าง thread รวมไปถึงการบริหารเวลาการทำงานให้กับ CPU แต่ละ core เอง การใช้ GCD สามารถทำได้สองทางด้วยกันคือใช้ Dispatch Queues ซึ่งเป็น C API และทางที่สองใช้ NSOperationQueue และในบทนี้จะได้ทำความเข้าใจการใช้งานทั้งสองแบบ

Dispatch Queues

ดิสแพทช์คิวคือเครื่องมือใช้ในการจัดการงานหรือที่เรียกว่า task (ต่อไปนี้จะใช้คำว่า task) อะไรควรทำก่อนหรือหลัง เช่น โหลดข้อมูลจากเซิฟเวอร์ , อ่านข้อมูลจากฮาร์ดดิส , คำนวนค่าต่างๆ การประกาศ task สามารถเขียนด้วยฟังชั่น หรือจะใช้บล็อกก็ได้เช่นเดียวกัน การจัดลำดับการทำงานของ dispatch queues เป็นแบบ FIFO (First In – First Out) หาก task ใดเข้ามาในคิวก่อนก็จะได้รับสิทธิให้ทำงานก่อน ดิสแพทช์คิวได้แบ่งออกเป็นทั้งหมด 3 แบบด้วยกันคือ

Serial (private dispatch queue) เหมาะกับงานที่ต้องใช้ทรัพยากรร่วมกัน (shared resource) เนื่องจากดิสแพทช์คิวแบบนี้ อนุญาติให้ task ทำงานได้ทีละหนึ่ง task เท่านั้น ผู้ใช้สามารถสร้างคิวแบบนี้ได้ไม่จำกัด และดิสแพทช์คิวแต่ละคิวจะแยกการทำงานกันออกจากกัน เช่น โปรแกรมมีทั้งหมด 3 คิว โดยแต่ละคิวก็มี task เป็นของตัวเอง เมื่อให้โปรแกรมทำงาน คิวทั้ง 3 สามารถที่จะทำงานไปพร้อมกันได้ อย่างไรก็ตามคิวแต่ละคิวจะอนุญาติให้ task ได้ทำงานได้เพียงทีละ task เท่านั้น

serial

Concurrent (global dispatch queue) เป็นคิวที่อนุญาติให้ task ทำงานพร้อมกันได้มากกว่าหนึ่ง task และยังทำงานตามลำดับของ task ที่เข้ามาในดิสแพทช์คิว จำนวนของคิวที่สามารถสร้างได้นั้นขึ้นอยู่ทรัพยากรของระบบ เมื่อดิสแพทช์คิวทำงาน คิวจะสร้างเทรดขึ้นมาเพื่อรองรับ task และมีการบริหารจัดการโดยคิวเอง เช่นเดียวกับคิวแบบ serial

concurrent

Main dispatch queue อนุญาติให้ task ทำงานได้พร้อมกันเช่นเดียวกันกับ concurrent ดิสแพทช์คิวนี้จะไม่สร้างเทรดใหม่เหมือนกับสองคิวทีผ่านมา แต่จะให้ task ทำงานที่ Application Main Thread แทน คิวนี้มีการทำงานที่ main thread ดังนั้นผู้ใช้จะไม่ได้สร้างคิวขึ้นมาเอง แต่จะเรียกใช้ฟังชั่นเพื่อขอ main dispatch queue จากระบบ
เมื่อเข้าใจการทำงานของคิวทั้งสามแบบแล้ว ต่อไปก็ลงมือเขียนโปรแกรมกัน ซึ่งเป็นตัวอย่างการใช้งาน GCD อย่างง่ายๆ เช่น การดาวน์โหลด รูปภาพจากอินเทอร์เน็ต พร้อมกันหลายๆรูป Continue reading Objective-C Programming Chapter 19 (Part1)