2012-02-27 38 views
9

Nó sẽ là một sự khác biệt lớn giữa điều này hai scenarious:Đa luồng so với Đa phiên bản - Lựa chọn nào?

  1. một thể hiện của ứng dụng tạo ra 100 chủ đề để xử lý một số công việc
  2. 10 trường hợp của cùng một ứng dụng tạo ra 10 bài mỗi để xử lý công việc (tổng số 100)

Số lượng chủ đề trong cả hai trường hợp sẽ giống nhau. Có một số hiệu suất hay bất kỳ loại cải tiến nào của cái khác?

Ví dụ - là ứng dụng bảng điều khiển ví dụ, vì vậy trong trường hợp thứ hai, sẽ là 10 ứng dụng giao diện điều khiển đang chạy. mỗi ứng dụng có thư mục riêng.

+3

3. Không tạo 100 chuỗi hoạt động đồng thời trừ khi bạn đang dùng bút chì với toàn bộ bộ xử lý. –

+0

Các quy trình của bạn có cần giao tiếp không? – Jimmy

+0

Apolagize cho câu trả lời không chính xác (được xóa). Tôi đã thử nghiệm kịch bản trên và tôi thấy quá trình xử lý đa luồng đơn lẻ thực sự nhanh hơn ứng dụng đa tiến trình. Sẽ cố gắng tự mình hiểu lý do. – Jimmy

Trả lời

4

Chủ đề sử dụng ít tài nguyên hơn quy trình để lựa chọn về mặt lý thuyết 1 sẽ là "tốt hơn". Tuy nhiên, bạn có thể sẽ không nhận thấy sự khác biệt nhiều giữa hai, bởi vì 100 thread riêng biệt hoặc xử lý tất cả chạy đồng thời và chiến đấu cho cùng một tài nguyên O/S được đảm bảo khá nhiều để xay hệ thống của bạn dừng lại.

Tôi sẽ chọn tùy chọn 3 - một quá trình có chứa một nhóm luồng khá nhỏ. Bằng cách đó, một số công việc sẽ thực hiện đồng thời và phần còn lại sẽ xếp hàng và đợi đến lượt họ. Cách tiếp cận này cũng có quy mô tốt nếu một số lượng lớn các công việc sẽ được chạy.

Xem ThreadPool lớp, hoặc tốt hơn là, một trong nhiều trừu tượng cấp cao trên đầu trang của nó (ví dụ các task library, hoặc thậm chí đơn giản cũ asynchronous delegates).

0

Câu hỏi kỳ lạ như vậy, khó tìm được ứng dụng thực tế..Nhưng tôi sẽ tưởng tượng tùy chọn 1 sẽ tốt hơn từ quan điểm hiệu suất. Với việc chạy 10 phiên bản của cùng một ứng dụng, sẽ có nhiều công việc đang được thực hiện hơn. (dọn dẹp, đăng ký, giao diện điều khiển mở, vv)

Chỉnh sửa * Vì với tùy chọn 1, bạn có thể xếp hàng công việc và để xử lý luồng tải.

2

Lựa chọn 2 có (ít nhất) các chi phí sau:

  • More quá trình đối tượng
  • More mỗi quá trình bộ nhớ tĩnh
  • Nhiều trường hợp của CLR và mã JITted
  • tắc bối cảnh cần phải chuyển đổi không gian địa chỉ (rất tốn kém)
  • Ít cơ hội chia sẻ cấu trúc dữ liệu ứng dụng
  • Bạn cần cr oss-quá trình giao tiếp. các cuộc gọi phương pháp đơn giản trở thành hoạt động IPC
  • Nhiều công việc cho bạn
  • Nhiều cơ hội cho các lỗi (thông tin liên lạc IPC, bom ngã ba, ...)
  • Tệ hơn debuggability
  • Không tích hợp cân bằng tải qua thread- pool
  • Đồng bộ hóa dễ bị lỗi và dễ bị lỗi hơn. Ít nội dung được tích hợp sẵn và chậm hơn

Tại sao bạn chọn (2) nếu bạn có thể chọn (1)? Có các lý do hợp lệ, nhưng những lý do này khá đặc biệt:

  • Bạn cần có khả năng chịu đựng sự hỏng hóc bộ nhớ tùy ý. Đây không phải là trường hợp bình thường (không phải ở tất cả!)
  • Bạn cần có khả năng tiêu đề. Điều này không thể được thực hiện một cách đáng tin cậy bên trong CLR cho các luồng đơn. Nhưng bạn có thể làm điều đó hợp tác mà thường là lựa chọn tốt hơn anyway
  • Chủ đề của bạn cần phải chạy theo người dùng khác nhau và như vậy. Điều này gần như không bao giờ xảy ra.

Nói chung, càng ít quy trình càng tốt.

+0

Tôi đã thêm nhiều nội dung thông qua chỉnh sửa. – usr

1

Vâng, đó sẽ là một sự khác biệt lớn. Có ưu và nhược điểm trong mỗi cách tiếp cận:

  • Mức tiêu thụ bộ nhớ. Rõ ràng, mỗi trong 10 quy trình sẽ yêu cầu tạo không gian địa chỉ riêng của chúng, v.v.
  • Tính đơn giản của truyền thông/đồng bộ hóa. Mặc dù tương đối dễ dàng để giao tiếp/đồng bộ hóa chủ đề (bạn có thể sử dụng các phần quan trọng, trong đó là một trong những cách hiệu quả nhất), sẽ khó thực hiện hơn giữa các quy trình . Trong kịch bản của bạn với 10 quy trình và 10 chủ đề, bạn sẽ phải thực hiện cả hai cách.
  • Sự cố. Nếu một trong các luồng trong quá trình thực hiện điều gì đó sai, toàn bộ quá trình sẽ chết.

Cá nhân tôi muốn có một quy trình/nhiều chủ đề. Tuy nhiên, nó thực sự phụ thuộc vào nhiệm vụ.

+0

OP có nói rằng các quy trình của ông cần phải giao tiếp không? – Jimmy

+0

Tôi đã thử nghiệm kịch bản thực tế và thấy nhiều quy trình chậm hơn. Bạn đúng rồi. Tôi đã xóa câu trả lời sai. – Jimmy

2

Tùy thuộc vào những gì bạn đang làm, nhưng trong hầu hết các trường hợp, Tùy chọn 1 sẽ có hiệu suất tốt nhất và sẽ dễ dàng thực hiện nhất.
Để cung cấp cho bạn một câu trả lời hoàn chỉnh hơn tôi sẽ cần phải biết những điều sau:

  • Are 100 Chủ đề tất cả thực hiện các nhiệm vụ giống nhau không?
  • 100 Chủ đề có truy cập cùng một dữ liệu không?
  • Các tác vụ được xử lý bởi các chuỗi sẽ có thời gian tự nhiên giảm xuống (chờ quá trình khác hoàn thành hoặc tài nguyên có sẵn)?
  • Các tác vụ được xử lý bởi các chuỗi sẽ cố gắng truy cập vào một tài nguyên giới hạn (như đĩa cứng hoặc card mạng)?
  • Có thể xử lý bao nhiêu chủ đề đồng thời cùng một lúc (ví dụ bộ xử lý 4 lõi với Hyper-Threading có thể xử lý 8 luồng, bộ xử lý 4 lõi không có Hyper-Threading có thể xử lý 4 luồng)?
  • Điều gì sẽ xảy ra nếu xảy ra sự cố trên chuỗi? Quá trình này có bị lỗi hay không, là chuỗi đã khởi động lại chưa?

Nếu tất cả các chủ đề đều thực hiện cùng một tác vụ, việc giữ chúng cùng nhau sẽ dễ dàng hơn cho người dùng cuối và nhà phát triển sau, vì mọi thứ đều ở cùng một nơi.

Nếu tất cả các chủ đề đều truy cập cùng một dữ liệu thì việc lưu giữ chúng trong cùng một quy trình sẽ cho phép bạn chia sẻ dữ liệu giữa các chủ đề (mặc dù xem các điều kiện chủng tộc khi thay đổi dữ liệu) và giảm bộ nhớ chân. Bạn cũng có thể kết hợp các luồng để truy cập dữ liệu từ cùng một khối, vì vậy mọi thứ có thể được lưu trữ trên CPU, giảm hiệu ứng của độ trễ của bộ nhớ, mặc dù đây không phải là điều tôi khuyên bạn nên thử.

Vì nhiều câu trả lời đang đưa ra lời khuyên về cách triển khai dự án của bạn, biết liệu mỗi luồng được thiết kế để sử dụng đầy đủ CPU mọi lúc nó đang chạy hay đây là các tác vụ nền. đi ngủ sẽ giúp chúng tôi đưa ra đề xuất chính xác cho tình huống của bạn.

Biết phần cứng mà quy trình sẽ chạy sẽ giúp chúng tôi cung cấp đề xuất chính xác cho trường hợp của bạn.

Nếu chuỗi không thành công, điều gì sẽ xảy ra? Nếu chuỗi không thành công một lần mỗi ngày, người dùng có cần can thiệp, ngừng quá trình và khởi động lại không? Nếu vậy thì mọi công việc chưa được thực hiện trên các chủ đề khác sẽ bị mất. Trong trường hợp này, việc mỗi thread chạy trong tiến trình riêng của nó sẽ cho bạn lợi ích của việc chỉ mất đi tiến trình thất bại.


Tùy chọn của Christian Hayter 3 có ý nghĩa nhưng không phải lúc nào cũng phù hợp với C#.
Nếu bạn nhìn vào documentation, nó khẳng định:

Một hệ điều hành threadid không có mối quan hệ cố định to a thread quản lý, bởi vì một máy chủ không được quản lý có thể kiểm soát các mối quan hệ giữa các chủ đề quản lý và không được quản lý. Cụ thể, một máy chủ tinh vi có thể sử dụng CLR Hosting API để lên lịch cho nhiều luồng được quản lý dựa trên cùng một luồng hệ điều hành hoặc để di chuyển một chuỗi được quản lý giữa các luồng hệ điều hành khác nhau.

Về cơ bản, điều này có nghĩa là khung .Net sẽ gộp chủ đề của bạn nếu cảm thấy đó là ý tưởng hay. Điều này có nhiều khả năng xảy ra nếu các tiến trình của bạn đang sử dụng nhiều luồng hơn, trong khi tổng số luồng có thể sẽ khá giống nhau giữa các quy trình đa luồng. Kết quả là tôi mong đợi quá trình 1, 100 chủ đề giải pháp để sử dụng tổng số chủ đề ít hơn thì 10 tiến trình, 10 luồng mỗi (một cái gì đó như 10 đến 40, nhưng bạn sẽ phải kiểm tra).

Điều đó đang được nói, khung sẽ được đoán, vì vậy trong một số trường hợp, Thread Pools sẽ là một lựa chọn tốt hơn. Trước tiên, hãy nhớ đọc số documentation vì có một số trường hợp không nên sử dụng Hồ bơi chủ đề. Hướng dẫn nhanh về Bể bơi có thể được tìm thấy trên MSDN. Ngoài ra còn có một số thread sẽ loại bỏ thời điểm sử dụng Thread Pools.


Nếu bạn cung cấp thêm thông tin thì tôi sẽ cố đưa ra câu trả lời chính xác hơn. Nếu không, tùy chọn 1 (và có thể là tùy chọn 3) là lựa chọn tốt hơn trong hầu hết các trường hợp.