2012-06-11 42 views
39

Tôi đang viết một chương trình iOS phức tạp vừa phải cần có nhiều luồng cho một số thao tác dài hơn của nó (phân tích cú pháp, kết nối với mạng ... v.v.). Tuy nhiên, tôi đang bối rối như những gì sự khác biệt là giữa dispatch_get_global_queuedispatch_queue_create.Sự khác biệt giữa dispatch_get_global_queue và dispatch_queue_create là gì?

Tôi nên sử dụng cái nào và bạn có thể cho tôi giải thích đơn giản về sự khác biệt nói chung không? Cảm ơn.

+1

Ya .. u đã chọn câu trả lời sai. Câu trả lời của Robert Ryan phù hợp hơn –

Trả lời

68

Khi mô tả documentation, hàng đợi toàn cầu phù hợp với nhiệm vụ đồng thời (nghĩa là bạn sẽ gửi nhiều tác vụ không đồng bộ và bạn hoàn toàn hài lòng nếu chạy đồng thời) và nếu bạn không muốn gặp phải lý thuyết chi phí tạo và hủy hàng đợi của riêng bạn.

Việc tạo hàng đợi của riêng bạn rất hữu ích nếu bạn cần một hàng đợi nối tiếp (nghĩa là bạn cần các khối được gửi đi để thực thi từng lần một). Điều này có thể hữu ích trong nhiều trường hợp, chẳng hạn như khi mỗi tác vụ phụ thuộc vào điều kiện trước đó hoặc khi phối hợp tương tác với một số tài nguyên được chia sẻ từ nhiều luồng.

Ít phổ biến hơn, nhưng bạn cũng sẽ muốn tạo hàng đợi của riêng mình nếu bạn cần sử dụng barriers cùng với hàng đợi đồng thời. Trong trường hợp đó, hãy tạo một hàng đợi đồng thời (tức là dispatch_queue_create với tùy chọn DISPATCH_QUEUE_CONCURRENT) và sử dụng các rào cản cùng với hàng đợi đó. Bạn không bao giờ nên sử dụng các rào cản trên hàng đợi toàn cầu.

Tư vấn chung của tôi là nếu bạn cần một hàng đợi nối tiếp (hoặc cần phải sử dụng các rào cản), sau đó tạo một hàng đợi. Nếu bạn không, hãy tiếp tục và sử dụng hàng đợi toàn cầu và bỏ qua chi phí tạo của riêng bạn.


Nếu bạn muốn có một hàng đợi đồng thời, nhưng muốn kiểm soát có bao nhiêu hoạt động có thể chạy đồng thời, bạn cũng có thể xem xét sử dụng NSOperationQueue trong đó có một tài sản maxConcurrentOperationCount. Điều này có thể hữu ích khi thực hiện các hoạt động mạng và bạn không muốn quá nhiều yêu cầu đồng thời được gửi đến máy chủ của bạn.

+2

Mặc dù lưu ý rằng trong Lion, bây giờ có thể nhận được một hàng đợi đồng thời từ 'dispatch_queue_create()' bằng cách chuyển 'DISPATCH_QUEUE_CONCURRENT'. Nó không được chỉ định (và có lẽ không quan trọng) cho dù điều này sẽ chỉ trả về một trong những hàng đợi toàn cầu hiện có. –

+1

Tôi nên thêm, "có lẽ chức năng đó sẽ đến với iOS cuối cùng". –

+1

Được thăng hạng để chỉ ra chính xác sự khác biệt về thời hạn của hàng đợi đồng thời và hàng đợi. – user523234

0

Một trả về hàng đợi toàn cầu hiện tại, cột kia tạo hàng đợi mới. Thay vì sử dụng GCD, tôi sẽ xem xét việc sử dụng hàng đợi hoạt động và NSOperation. Bạn có thể tìm thêm thông tin về nó in this guide. Thông thường, bạn muốn các thao tác thực hiện đồng thời, bạn muốn tạo hàng đợi của riêng bạn và đặt các hoạt động của bạn vào đó.

+0

Chỉ cần làm rõ, nếu bạn đang tạo một hàng đợi công văn, nó sẽ nối tiếp. Nếu bạn đang sử dụng hàng đợi công văn toàn cầu, nó có thể đồng thời (nhưng không được bảo đảm như vậy). Tôi cho rằng việc tạo hàng đợi của luật sư của bạn cho đồng thời có liên quan đến hàng đợi hoạt động, không phải là hàng đợi gửi đi. (Tôi biết bạn biết điều đó, nhưng tôi chỉ muốn chắc chắn rằng người đọc không bị nhầm lẫn.) – Rob

+1

Vâng, tôi đang nói về hàng đợi hoạt động. Tôi đã phải đối mặt với cùng một vấn đề một thời gian trước đây, và khi tôi tạo ra hàng đợi hoạt động của riêng mình mà không có bất kỳ cấu hình nào khác, các hoạt động được thêm vào trong nó được thực hiện đồng thời với nhau. –

40

Chỉ được đăng trong một câu trả lời khác nhau, nhưng đây là một cái gì đó tôi đã viết khá một thời gian trở lại:

Cách tốt nhất để khái niệm hàng đợi là lần đầu tiên nhận ra rằng ở mức độ thấp rất, chỉ có hai loại hàng đợi: nối tiếp và đồng thời.

Hàng đợi nối tiếp là một vợ một chồng nhưng không được cam kết. Nếu bạn cung cấp cho một loạt các nhiệm vụ cho mỗi hàng đợi nối tiếp, nó sẽ chạy chúng mỗi lần, chỉ sử dụng một luồng tại một thời điểm. Khía cạnh không cam kết là hàng đợi nối tiếp có thể chuyển sang một luồng khác giữa các nhiệm vụ. Hàng đợi nối tiếp luôn chờ một công việc hoàn thành trước khi chuyển sang mục tiếp theo. Do đó các nhiệm vụ được hoàn thành theo thứ tự FIFO. Bạn có thể tạo bao nhiêu hàng đợi nối tiếp khi cần với dispatch_queue_create.

Hàng đợi chính là hàng đợi nối tiếp đặc biệt. Không giống như các hàng đợi nối tiếp khác, mà không được cam kết, trong đó họ "đang hẹn hò" nhiều chủ đề nhưng chỉ một lần, hàng đợi chính là "kết hôn" với chủ đề chính và tất cả các tác vụ được thực hiện trên đó.Công việc trên hàng đợi chính cần phải hoạt động tốt với runloop để các hoạt động nhỏ không chặn giao diện người dùng và các bit quan trọng khác. Giống như tất cả các hàng đợi nối tiếp, các tác vụ được hoàn thành theo thứ tự FIFO.

Nếu hàng đợi nối tiếp là một vợ chồng, thì hàng đợi đồng thời là không liên quan. Họ sẽ gửi nhiệm vụ cho bất kỳ chủ đề có sẵn hoặc thậm chí tạo chủ đề mới tùy thuộc vào tải hệ thống. Họ có thể thực hiện nhiều tác vụ đồng thời trên các chủ đề khác nhau. Điều quan trọng là các tác vụ được gửi đến hàng đợi toàn cầu là an toàn luồng và giảm thiểu các tác dụng phụ. Các tác vụ được gửi để thực hiện theo thứ tự FIFO, nhưng thứ tự hoàn thành không được đảm bảo. Theo văn bản này, chỉ có ba hàng đợi đồng thời và bạn không thể tạo chúng, bạn chỉ có thể tìm nạp chúng với dispatch_get_global_queue.

chỉnh sửa: bài đăng trên blog mở rộng trên câu trả lời này: http://amattn.com/p/grand_central_dispatch_gcd_summary_syntax_best_practices.html

+2

Tốt nhất. Câu trả lời. Không bao giờ. –

+1

Liên kết bài đăng trên blog đã chết. –

+0

Dường như vẫn hoạt động với tôi. Gần đây tôi đã cập nhật các công cụ blog, do đó, có một địa chỉ kinh điển mới ở đây: http://amattn.com/p/grand_central_dispatch_gcd_summary_syntax_best_practices.html – amattn

Các vấn đề liên quan