Concurrency Programming Guide

Bài viết Concurrency Programming Guide thuộc chủ đề về Hỏi đáp thắc mắt đang được rất nhiều bạn lưu tâm đúng không nào !! Hôm nay, Hãy cùng sotaythongthai.vn tìm hiểu Concurrency Programming Guide trong bài viết hôm nay nha !

Các bạn đang xem nội dung : “Concurrency Programming Guide”

Bài viết này dành cho ai?

Lập trình đồng bộ là một kỹ thuật lập trình trung cấp. Để hiểu được bạn cần phải quen thuộc với các API bất đồng bộ như URLSession, và đơn giản viết và dùng những completion handler closures. Nếu bạn chưa biết những vấn đề trên, bạn cũng khả năng xem qua như 1 tài liệu tham khảo, và đừng bắt mình phải hiểu hết vấn đề.

Yếu tố lịch sử

Trong lịch sử phát triển máy tính, khối lượng công việc lớn nhất mà máy tính khả năng xử lý trong một đơn vị thời gian được quyết định bởi tốc độ đồng hồ của CPU. Để tăng tốc CPU và thu nhỏ chip bán dẫn, người ta cố gắng nén một lượng lớn các đèn bán dẫn vào trong một diện tích nhỏ nhất. mặc khác cuộc đua tăng tốc cho lõi CPU bị dừng lại do các giới hạn về phần cứng và nhiệt độ. Để tiếp tục tăng tốc cho CPU, người ta bắt đầu tìm một giải pháp khác để tăng tổng hiệu suất của CPU lên, cùng lúc ấy tăng hiệu suất tiêu thụ điện. Và giải pháp đó là đưa nhiều lõi hơn vào trong một CPU thay cho một lõi. Việc xử lý được đưa cho nhiều Core cùng xử lý, vì thế tổng hiệu năng được tăng lên. Thoạt đầu, Giải pháp nghe có vẻ rất hay nhưng vấn đề lại nằm ở phần mềm. Để tận dụng được lợi thế xử lý nhiều core trong các ứng dụng thì không phải là đơn giản. Trong quá khứ, để dùng được các core này, chúng ta phải xử lý việc khởi tạo và quản lý các thread này một cách thủ công. Việc này thực sự điều kiện với hầu hết các lập trình viên, bởi việc xác định được con số tối ưu của các thread trong từng hoàn cảnh dựa trên khối lượng tải hệ thống hiện thời , và phần cứng ở dưới là không hề đơn giản.

Để xử lý vấn đề điều kiện này, cả iOS và OSX đề ra một cách tiếp cận khác cho việc xử lý cùng lúc ấy đó là: Thay vì phải tạo các threads một cách trực tiếp, các ứng dụng chỉ đơn giản là gửi các task vào các hàng đợi Queue. Còn việc khởi tạo các thread thế nào, bao nhiêu thread được đẩy cho hệ thống quyết định. Bằng cách để cho hệ thống quản lý quản lý các thread, các ứng dụng khả năng đạt được một mức độ linh hoạt mà cách xử lý cũ không bao giờ đạt được. cùng lúc ấy lập trình viên có được một mô hình lập trình đơn giản mà kết quả hơn.

Concurrency là gì?

Xử lý cùng lúc ấy – Concurrency – là việc nhiều task được xử lý cùng một lúc.

Tại sao app của chúng ta lại cần xử lý cùng lúc ấy – Concurrency?

  • Để giữ cho UI luôn trong trạng thái được đáp ứng.
  • đẩy nhanh xử lý, tận dụng tối đa sức mạnh của kiến trúc chip đa nhân.

Nếu chúng ta xử lý một task non-UI nặng trên main thread, task này sẽ block lại main thread và app của chúng ta không thể tiếp nhận được những tương tác của người dùng nữa.

Lúc này chúng ta cần chuyển các tác vụ nặng non-UI task sang một thread khác để xử lý, và main thread sẽ tiếp tục làm các nhiệm vụ khác trong đó có nhiệm vụ quan trọng nhất là đón nhận những tương tác của người dùng.

một vài khái niệm của lập trình cùng lúc ấy

Concurrency

Concurrency không những là một khái niệm cho thiết bị có chip nhiều nhân. Trong những thiết bị đơn nhân, chúng ta vẫn khả năng xử lý được đa luồng dựa vào cơ chế time-slicing để chuyển ngữ cảnh.

Queue

Queue là hàng đợi các công việc, vận hành theo nguyên tắc FIFO, task nào vào trước thì sẽ được thực hiện trước, task nào vào sau sẽ được thực hiện sau. Có hai loại hàng đợi: Serial Queue: là hàng đợi thực hiện theo tuần tự. Trong một thời điểm chỉ có 1 task được thực thi. Khi nào task này thực thi xong thì task khác mới bắt đầu. Ví dụ tiêu biểu của hàng đợi này là Main thread.

Concurrent Queue: là hàng đợi thực hiện cùng lúc ấy. Trong một thời điểm khả năng có nhiều task được thực hiện cùng một lúc. Hệ thống sẽ tuỳ vào tải hiện thời của hệ thống và cấu hình phần cứng thực tế để khởi tạo và cấp phát các Thread để xử lý các tác vụ.

So sánh giữa Serial Queue và Concurrent Queue

Synchronous và Asynchronous

Đầu vào của các queue là các closure. Các closure này được đánh dấu về cách thức thực hiện nó trước khi gửi đến một queue Có hai cách thức thực hiện của một closure: Nếu task đánh dấu là Synchronous thì task này sẽ block lại queue mà nó được gọi, không cho phép queue đó thực thi thêm task nào khác trong thời gian nó đang chạy. Nếu task được đánh dấu là Asynchronous thì task này được gọi và ngay sau đó nó trả quyền điều khiển cho hàm gọi nó và hàng đợi sẽ thực thi một closure tiếp theo (nếu có đủ queue để thực thi).

Mối quan hệ tình dục giữa Synchronous, Asynchronous VS Serial Queue, Concurrent Queue

Synchronous, Asynchronous là phương pháp thức thực hiện của 1 task. Serial Queue, Concurrent Queue là đích đến của task đó.

Synchronous, Asynchronous nói cho bạn biết là queue hiện thời có phải đợi task hoàn thành rồi mới gọi task mới hay không Serial Queue, Concurrent Queue thì cho bạn biết là với queue hiện thời, bạn có 1 thread hay nhiều thread. 1 Task được thực hiện 1 lúc hay nhiều task được thực hiện cùng lúc ấy.

Trường hợp gửi 2 async task vào serial queue

func simpleQueues() let queue = DispatchQueue(label: “com.bigZero.GCDSamples”) sentayho.com.vn for i in 0..<5 print(“🔵 (i) -( sentayho.com.vnent))”) sentayho.com.vn for i in 0..<5 print(“⚾️ (i) – (Thread.current))”) for i in 0..<10 print(“❤️ (i) – (Thread.current)”)

khi gửi một async task in 🔵 vào trong queue, ngay lập tức nó trả quyền điều khiển cho function gọi nó. vì thế chúng ta tiếp tục chạy được dòng lệnh gửi một async task thứ 2 vào trong queue – task in ⚾️ async task thứ 2 sau khi được đẩy vào trong Queue, nó ngay lập tức trả điều khiển lại cho function gọi nó và function simpleQueues() tiếp tục thực thi việc in ❤️ Do task 🔵 và task ⚾️ được đưa vào cùng 1 Serial Queue nên nó được chạy trên 1 thread theo cách thức tuần tự. Task ❤️được thực hiện trên thread hiện thời là main thread. (🔵 tuần tự ⚾️) // Main thread Task Vì main thread có mức độ ưu tiên cao nhất nên trong quy trình thực hiện, mặc dù số ❤️ bằng tổng số 🔵 + ⚾️. Nhưng khi thực hiện ❤️ vẫn thực hiện xong trước 2 task kia

🔵 0 -<NSThread: 0x610000078200>number = 3, name = (null)) ❤️ 0 – <NSThread: 0x610000070d80>number = 1, name = main ❤️ 1 – <NSThread: 0x610000070d80>number = 1, name = main 🔵 1 -<NSThread: 0x610000078200>number = 3, name = (null)) ❤️ 2 – <NSThread: 0x610000070d80>number = 1, name = main 🔵 2 -<NSThread: 0x610000078200>number = 3, name = (null)) ❤️ 3 – <NSThread: 0x610000070d80>number = 1, name = main ❤️ 4 – <NSThread: 0x610000070d80>number = 1, name = main 🔵 3 -<NSThread: 0x610000078200>number = 3, name = (null)) ❤️ 5 – <NSThread: 0x610000070d80>number = 1, name = main 🔵 4 -<NSThread: 0x610000078200>number = 3, name = (null)) ❤️ 6 – <NSThread: 0x610000070d80>number = 1, name = main ❤️ 7 – <NSThread: 0x610000070d80>number = 1, name = main ⚾️ 0 – <NSThread: 0x610000078200>number = 3, name = (null)) ❤️ 8 – <NSThread: 0x610000070d80>number = 1, name = main ❤️ 9 – <NSThread: 0x610000070d80>number = 1, name = main ⚾️ 1 – <NSThread: 0x610000078200>number = 3, name = (null)) ⚾️ 2 – <NSThread: 0x610000078200>number = 3, name = (null)) ⚾️ 3 – <NSThread: 0x610000078200>number = 3, name = (null)) ⚾️ 4 – <NSThread: 0x610000078200>number = 3, name = (null))

Trường hợp gửi 2 task Sync vào Serial Queue

func simpleQueues() let serialQueue = DispatchQueue(label: “com.bigZero.GCDSamples”) sentayho.com.vn for i in 0..<5 print(“🔵 (i) -( sentayho.com.vnent))”) sentayho.com.vn for i in 0..<5 print(“⚾️ (i) – (Thread.current))”) for i in 0..<10 print(“❤️ (i) – (Thread.current)”)

Khi gửi sync task 🔵 vào serialQueue, task 🔵 block lại function simpleQueues không cho thực hiện tiếp các tác vụ tiếp theo. Lúc này main thread sẽ được rảnh (vì main queue đang bị block lại), vì thế nó được cấp phát để thực hiện task 🔵. Sau khi thực hiện xong task 🔵, task ⚾️ bắt đầu được gọi và cũng tiếp tục như trên. cuối cùng task ❤️ được gọi trên main queue, và với tất cả các task vụ trên main queue đều sẽ được ưu tiên thực hiện trên main thread.

🔵 0 -<NSThread: 0x610000073200>number = 1, name = main) 🔵 1 -<NSThread: 0x610000073200>number = 1, name = main) 🔵 2 -<NSThread: 0x610000073200>number = 1, name = main) 🔵 3 -<NSThread: 0x610000073200>number = 1, name = main) 🔵 4 -<NSThread: 0x610000073200>number = 1, name = main) ⚾️ 0 – <NSThread: 0x610000073200>number = 1, name = main) ⚾️ 1 – <NSThread: 0x610000073200>number = 1, name = main) ⚾️ 2 – <NSThread: 0x610000073200>number = 1, name = main) ⚾️ 3 – <NSThread: 0x610000073200>number = 1, name = main) ⚾️ 4 – <NSThread: 0x610000073200>number = 1, name = main) ❤️ 0 – <NSThread: 0x610000073200>number = 1, name = main ❤️ 1 – <NSThread: 0x610000073200>number = 1, name = main ❤️ 2 – <NSThread: 0x610000073200>number = 1, name = main ❤️ 3 – <NSThread: 0x610000073200>number = 1, name = main ❤️ 4 – <NSThread: 0x610000073200>number = 1, name = main ❤️ 5 – <NSThread: 0x610000073200>number = 1, name = main ❤️ 6 – <NSThread: 0x610000073200>number = 1, name = main ❤️ 7 – <NSThread: 0x610000073200>number = 1, name = main ❤️ 8 – <NSThread: 0x610000073200>number = 1, name = main ❤️ 9 – <NSThread: 0x610000073200>number = 1, name = main

Bây giờ chúng ta thay đổi ngay 1 chút, task thứ 2 chúng ta chuyển thành async

func simpleQueues() let serialQueue = DispatchQueue(label: “com.bigZero.GCDSamples”) sentayho.com.vn for i in 0..<5 print(“🔵 (i) -( sentayho.com.vnent))”) sentayho.com.vn for i in 0..<5 print(“⚾️ (i) – (Thread.current))”) for i in 0..<10 print(“❤️ (i) – (Thread.current)”)

cũng như ở trên Khi gửi sync task 🔵 vào serialQueue, task 🔵 block lại function simpleQueues không cho thực hiện tiếp các tác vụ tiếp theo. Lúc này main thread sẽ được rảnh (vì main queue đang bị block lại), vì thế nó được cấp phát để thực hiện task 🔵. Sau khi thực hiện xong task 🔵, task ⚾️ bắt đầu được gọi. Do task ⚾️ là async nên ngay lập tức nó trả lại quyền điều khiển cho function gọi nó và task ❤️ được gọi ưu tiên trên main thread. Do main thread đang được dùng rồi, nên hệ thống cấp phát cho task ⚾️ một thread khác để xử lý vì thế ta có kết quả

🔵 0 -<NSThread: 0x6100000757c0>number = 1, name = main) 🔵 1 -<NSThread: 0x6100000757c0>number = 1, name = main) 🔵 2 -<NSThread: 0x6100000757c0>number = 1, name = main) 🔵 3 -<NSThread: 0x6100000757c0>number = 1, name = main) 🔵 4 -<NSThread: 0x6100000757c0>number = 1, name = main) ⚾️ 0 – <NSThread: 0x60800007a980>number = 4, name = (null)) ❤️ 0 – <NSThread: 0x6100000757c0>number = 1, name = main ⚾️ 1 – <NSThread: 0x60800007a980>number = 4, name = (null)) ❤️ 1 – <NSThread: 0x6100000757c0>number = 1, name = main ❤️ 2 – <NSThread: 0x6100000757c0>number = 1, name = main ⚾️ 2 – <NSThread: 0x60800007a980>number = 4, name = (null)) ❤️ 3 – <NSThread: 0x6100000757c0>number = 1, name = main ❤️ 4 – <NSThread: 0x6100000757c0>number = 1, name = main ⚾️ 3 – <NSThread: 0x60800007a980>number = 4, name = (null)) ❤️ 5 – <NSThread: 0x6100000757c0>number = 1, name = main ⚾️ 4 – <NSThread: 0x60800007a980>number = 4, name = (null)) ❤️ 6 – <NSThread: 0x6100000757c0>number = 1, name = main ❤️ 7 – <NSThread: 0x6100000757c0>number = 1, name = main ❤️ 8 – <NSThread: 0x6100000757c0>number = 1, name = main ❤️ 9 – <NSThread: 0x6100000757c0>number = 1, name = main

Trường hợp gửi 3 task Async vào Concurrent Queue

func concurrentQueues() let concurrentQueue = sentayho.com.vnal() sentayho.com.vn for i in 0..<10 print(“🔵 (i) – (Thread.current)”) sentayho.com.vn for i in 0..<10 print(“❤️ (i)- (Thread.current)”) sentayho.com.vn for i in 0..<10 print(“⚾️ (i)- (Thread.current)”)

Do 3 task đều là async nên cả 3 task đều được đưa vào trong concurrentQueue. Lúc này hệ thống sẽ cấp phát cho concurrentQueue 3 thread để thực hiện cùng lúc ấy 3 task trên 3 thread khác nhau vì thế ta được

🔵 0 – <NSThread: 0x600000069480>number = 3, name = (null) ❤️ 0- <NSThread: 0x600000069500>number = 5, name = (null) ⚾️ 0- <NSThread: 0x608000066880>number = 1, name = main 🔵 1 – <NSThread: 0x600000069480>number = 3, name = (null) ⚾️ 1- <NSThread: 0x608000066880>number = 1, name = main ❤️ 1- <NSThread: 0x600000069500>number = 5, name = (null) ⚾️ 2- <NSThread: 0x608000066880>number = 1, name = main 🔵 2 – <NSThread: 0x600000069480>number = 3, name = (null) ❤️ 2- <NSThread: 0x600000069500>number = 5, name = (null) ⚾️ 3- <NSThread: 0x608000066880>number = 1, name = main 🔵 3 – <NSThread: 0x600000069480>number = 3, name = (null) ❤️ 3- <NSThread: 0x600000069500>number = 5, name = (null) ⚾️ 4- <NSThread: 0x608000066880>number = 1, name = main 🔵 4 – <NSThread: 0x600000069480>number = 3, name = (null) ❤️ 4- <NSThread: 0x600000069500>number = 5, name = (null) ⚾️ 5- <NSThread: 0x608000066880>number = 1, name = main 🔵 5 – <NSThread: 0x600000069480>number = 3, name = (null) ❤️ 5- <NSThread: 0x600000069500>number = 5, name = (null) ⚾️ 6- <NSThread: 0x608000066880>number = 1, name = main 🔵 6 – <NSThread: 0x600000069480>number = 3, name = (null) ❤️ 6- <NSThread: 0x600000069500>number = 5, name = (null) ⚾️ 7- <NSThread: 0x608000066880>number = 1, name = main 🔵 7 – <NSThread: 0x600000069480>number = 3, name = (null) ❤️ 7- <NSThread: 0x600000069500>number = 5, name = (null) ⚾️ 8- <NSThread: 0x608000066880>number = 1, name = main 🔵 8 – <NSThread: 0x600000069480>number = 3, name = (null) ❤️ 8- <NSThread: 0x600000069500>number = 5, name = (null) ⚾️ 9- <NSThread: 0x608000066880>number = 1, name = main 🔵 9 – <NSThread: 0x600000069480>number = 3, name = (null) ❤️ 9- <NSThread: 0x600000069500>number = 5, name = (null)

thay đổi ngay một chút. Ta cho task ❤️ trở thành sync. Khi add xong task ❤️, do task này là sync nên nó khoá queue lại, không cho add task ⚾️ vào nữa. Sau khi task ❤️ chạy xong, task ⚾️ mới được add vào concurrent Queue. Do vậy như kết quả, task ⚾️ chạy 1 mình cuối cùng.

❤️ 4- <NSThread: 0x610000065980>number = 1, name = main 🔵 4 – <NSThread: 0x618000064380>number = 3, name = (null) ❤️ 5- <NSThread: 0x610000065980>number = 1, name = main 🔵 5 – <NSThread: 0x618000064380>number = 3, name = (null) ❤️ 6- <NSThread: 0x610000065980>number = 1, name = main ❤️ 7- <NSThread: 0x610000065980>number = 1, name = main 🔵 6 – <NSThread: 0x618000064380>number = 3, name = (null) ❤️ 8- <NSThread: 0x610000065980>number = 1, name = main 🔵 7 – <NSThread: 0x618000064380>number = 3, name = (null) ❤️ 9- <NSThread: 0x610000065980>number = 1, name = main 🔵 8 – <NSThread: 0x618000064380>number = 3, name = (null) 🔵 9 – <NSThread: 0x618000064380>number = 3, name = (null) ⚾️ 0- <NSThread: 0x618000064380>number = 3, name = (null) ⚾️ 1- <NSThread: 0x618000064380>number = 3, name = (null) ⚾️ 2- <NSThread: 0x618000064380>number = 3, name = (null) ⚾️ 3- <NSThread: 0x618000064380>number = 3, name = (null) ⚾️ 4- <NSThread: 0x618000064380>number = 3, name = (null) ⚾️ 5- <NSThread: 0x618000064380>number = 3, name = (null) ⚾️ 6- <NSThread: 0x618000064380>number = 3, name = (null) ⚾️ 7- <NSThread: 0x618000064380>number = 3, name = (null) ⚾️ 8- <NSThread: 0x618000064380>number = 3, name = (null) ⚾️ 9- <NSThread: 0x618000064380>number = 3, name = (null)

Một lưu ý cuối cùng, chúng ta tạo queue, chúng ta khả năng quyết định rằng queue này sẽ chạy trên 1 thread hay nhiều thread bằng cách chỉ định loại queue là Serial hay Concurrent. Nhưng chính xác là thread nào thực thi các tác vụ thì chúng ta ko được quyền quyết định, việc đó được đẩy cho hệ thống quyết định dựa trên các yếu tố phần cứng, và tải hiện thời của hệ thống.

Bạn thấy bài viết thế nào?

Các câu hỏi về Concurrency Programming Guide

Team Sổ Tay Thông Thái mà chi tiết là Mỹ Chi đã biên soạn bài viết dựa trên tư liệu sẵn có và kiến thức từ Internet. Dĩ nhiên tụi mình biết có nhiều câu hỏi và nội dung chưa thỏa mãn được bắt buộc của các bạn.

Thế nhưng với tinh thần tiếp thu và nâng cao hơn, Mình luôn đón nhận tất cả các ý kiến khen chê từ các bạn & Quý đọc giả cho bài viêt Concurrency Programming Guide

Nếu có bắt kỳ câu hỏi thắc mắt nào vê Concurrency Programming Guide hãy cho chúng mình biết nha, mõi thắt mắt hay góp ý của các bạn sẽ giúp mình nâng cao hơn hơn trong các bài sau nha <3 Chốt lại nhen <3 Bài viết Concurrency Programming Guide ! được mình và team xem xét cũng như tổng hợp từ nhiều nguồn. Nếu thấy bài viết Concurrency Programming Guide Cực hay ! Hay thì hãy ủng hộ team Like hoặc share. Nếu thấy bài viết Concurrency Programming Guide rât hay ! chưa hay, hoặc cần bổ sung. Bạn góp ý giúp mình nha!!

Các Hình Ảnh Về Concurrency Programming Guide

Concurrency Programming Guide

Các từ khóa tìm kiếm cho bài viết #Concurrency #Programming #Guide

Tìm thêm tin tức về Concurrency Programming Guide tại WikiPedia

Bạn nên tham khảo thêm nội dung về Concurrency Programming Guide từ web Wikipedia tiếng Việt.◄

Tham Gia Cộng Đồng Tại

💝 Nguồn Tin tại: https://sotaythongthai.vn/

💝 Xem Thêm Câu Hỏi- Giải Đáp tại : https://mangraovat.edu.vn/hoi-dap/

Related Posts

About The Author

Add Comment