2010-01-03 43 views
14

Tôi không có nhiều kinh nghiệm về các chủ đề như Đồng thời và Đa luồng. Trong thực tế, trong hầu hết sự nghiệp phát triển web của tôi, tôi chưa bao giờ cần phải chạm vào những chủ đề này.Đồng thời và Đa luồng

Tôi cảm thấy nó là một khái niệm quan trọng, đặc biệt là cho các ứng dụng Desktop và về cơ bản bất kỳ ứng dụng nào khác không tạo HTML :).

Sau khi đọc một chút về đồng thời, có vẻ như được hỗ trợ tốt hơn bằng các ngôn ngữ như Go (ngôn ngữ lập trình google) và tôi không hiểu tại sao ngôn ngữ lại tốt hơn ngôn ngữ khác ở một khái niệm như concurrency, về cơ bản là về việc có thể xử lý fork() và tính toán song song, đúng không? Đây không phải là cách lập trình hoạt động sao?

Đa luồng có vẻ là một nhánh đồng thời vì nó cho phép bạn chạy mọi thứ song song bên dưới cùng một quy trình, mặc dù nó có vẻ là nền tảng cụ thể cách nó được triển khai.

Tôi đoán câu hỏi của tôi là, tại sao ngôn ngữ cụ thể sẽ tốt hơn tại đồng thời so với các ngôn ngữ khác và tại sao quá trình ing() là giải pháp tốt hơn là chỉ sử dụng chuỗi?

+0

nitpick - Go không phải là "lanu lập trình của Google". Đó là ngôn ngữ mà một số nhân viên của họ phát minh ra, nhưng cuối cùng tôi nghe nói, nó không được Google sử dụng trong nội bộ. –

+0

Nó nói "ngôn ngữ lập trình google", nhưng trong mọi trường hợp, tôi không thấy có gì sai khi đề cập đến một ngôn ngữ được Google phát triển và quảng cáo là "Google". – danben

Trả lời

28

Cũng có một điều, nhiều luồng không giống như nhiều quy trình, vì vậy fork() thực sự không áp dụng ở đây.

Xử lý đa luồng/song song là cứng. Trước tiên, bạn phải tìm ra cách thực sự phân vùng nhiệm vụ cần thực hiện. Sau đó, bạn phải phối hợp tất cả các bit song song, có thể cần phải nói chuyện với nhau hoặc chia sẻ tài nguyên. Sau đó, bạn cần phải củng cố các kết quả, mà trong một số trường hợp có thể được mỗi bit khó khăn như hai bước trước đó. Tôi đơn giản hóa ở đây, nhưng hy vọng bạn có được ý tưởng.

Câu hỏi của bạn là tại sao một số ngôn ngữ lại tốt hơn? Vâng, một số điều có thể làm cho nó dễ dàng hơn:

  • Tối ưu hóa cấu trúc dữ liệu không thay đổi. Bạn muốn dính vào cấu trúc bất biến bất cứ khi nào có thể trong xử lý song song, bởi vì chúng dễ dàng hơn nhiều để lý luận. Một số ngôn ngữ có hỗ trợ tốt hơn cho các ngôn ngữ này và một số ngôn ngữ có các tối ưu hóa khác nhau, tức là khả năng ghép các bộ sưu tập với nhau mà không cần sao chép thực tế trong khi vẫn thực thi tính bất biến. Bạn luôn có thể xây dựng các cấu trúc của riêng bạn như thế này, nhưng sẽ dễ dàng hơn nếu ngôn ngữ hoặc khung làm việc cho bạn.

  • Nguyên thủy đồng bộ hóa và dễ sử dụng chúng. Khi các luồng khác nhau chia sẻ trạng thái, chúng cần được đồng bộ hóa và có nhiều cách khác nhau để thực hiện điều này. Rộng hơn các mảng nguyên thủy đồng bộ mà bạn nhận được, công việc của bạn cuối cùng sẽ dễ dàng hơn. Hiệu suất sẽ bị ảnh hưởng nếu bạn phải đồng bộ hóa với một phần quan trọng thay vì khóa người đọc.

  • Giao dịch nguyên tử. Thậm chí tốt hơn nhiều mảng nguyên thủy đồng bộ không phải sử dụng chúng. Cơ sở dữ liệu là rất tốt ở đây; thay vì bạn, lập trình viên, phải tìm ra chính xác tài nguyên nào bạn cần khóa và khi nào và như thế nào, bạn chỉ cần nói với trình biên dịch hoặc thông dịch viên, "tất cả những thứ bên dưới dòng này cần phải xảy ra cùng nhau, vì vậy hãy đảm bảo không ai khác lộn xộn xung quanh với nó trong khi tôi đang sử dụng nó. " Và động cơ sẽ tìm ra khóa cho bạn. Bạn gần như không bao giờ có được loại đơn giản này trong một ngôn ngữ lập trình trừu tượng, nhưng bạn càng đến gần, thì càng tốt. Các đối tượng an toàn chủ đề kết hợp nhiều hoạt động phổ biến thành một là bắt đầu.

  • Tự động song song. Giả sử bạn phải lặp qua một danh sách dài các mục và chuyển đổi chúng bằng cách nào đó, như nhân với 50.000 10x10 ma trận. Nó sẽ không được tốt đẹp nếu bạn chỉ có thể nói với trình biên dịch: Hey, mỗi hoạt động có thể được thực hiện độc lập, do đó, sử dụng một lõi CPU riêng biệt cho mỗi một? Bạn không phải thực sự tự triển khai luồng? Một số ngôn ngữ hỗ trợ loại điều này; ví dụ, nhóm .NET đã làm việc trên PLINQ.

Đó chỉ là một vài ví dụ về những điều có thể làm cho cuộc sống của bạn dễ dàng hơn trong các ứng dụng song song/đa luồng. Tôi chắc chắn rằng có nhiều hơn nữa.

+3

+1. Các ngôn ngữ miễn phí có tác dụng phụ cũng giúp mọi việc trở nên dễ dàng hơn (những chức năng như Haskell). – LBushkin

1

Tại sao một số ngôn ngữ tốt hơn cho đồng thời so với các ngôn ngữ khác: tất cả đều phụ thuộc vào các công cụ mà ngôn ngữ cung cấp cho lập trình viên. Một số ngôn ngữ, như C++, cho phép bạn truy cập cấp thấp vào các luồng hệ thống. Java có tất cả các loại thư viện cung cấp các cấu trúc cho lập trình đồng thời, giống như các mẫu thiết kế (xem chốt, rào chắn, et al). Một số ngôn ngữ làm cho nó dễ dàng hơn những người khác để đối phó với chủ đề. Một số ngôn ngữ giúp bạn không chia sẻ trạng thái giữa các luồng, đó là một nguồn lỗi chính.

Và sau đó một số ngôn ngữ có các mô hình chuỗi cơ bản khác với các mô hình khác. Mô hình chuỗi của Python, như tôi đã hiểu, sử dụng một luồng hệ thống đơn lẻ và xử lý tất cả chính việc chuyển đổi ngữ cảnh, mà không phải là sạch vì nó chỉ là chi tiết như một lệnh Python đơn.

Tương tự, nó giống như hỏi tại sao một số ngôn ngữ xử lý các biểu thức thông thường, hoặc tìm kiếm, hoặc làm toán phức tạp khi cuối cùng tất cả các bit chỉ di chuyển xung quanh.

Chỉnh sửa: frunsi là chính xác, các chuỗi Python là các luồng hệ thống (dường như đây là quan niệm sai lầm phổ biến). Vấn đề tôi đã đề cập đến là với khóa thông dịch GIL hoặc toàn cầu, điều khiển việc thực thi luồng. Chỉ một luồng duy nhất có thể chạy trong trình thông dịch Python cùng một lúc và ngữ cảnh chỉ chuyển đổi giữa các lệnh. Kiến thức của tôi về đa luồng Python chủ yếu đến từ bài báo này: www.dabeaz.com/python/GIL.pdf. Có lẽ một chút tắt chủ đề, nhưng một tài liệu tham khảo tốt dù sao.

+0

Nhận xét về python là sai, có thể bạn đang nghĩ đến một số chủ đề nhẹ? Họ có một ý định khác. Xem http://docs.python.org/library/thread.html#module-thread. Mặc dù có (hoặc là) một vấn đề với một khóa thông dịch toàn cầu trong python, nhưng tuyên bố của bạn là rõ ràng sai. – Frunsi

0

không có ngôn ngữ nào tốt hơn ngôn ngữ khác, tất cả đều là về các khái niệm. Làm mọi thứ một cách đồng thời bởi các quá trình tiêu thụ thường nhiều tài nguyên hơn so với các luồng (có thể được xem là các quy trình nhẹ) một số ngôn ngữ đi kèm với quá dễ sử dụng libs. Các luồng Java dễ sử dụng, các chuỗi Posix (C trên Unix) phức tạp hơn một chút.

0

Đồng thời về cơ bản là có thể fork() các quy trình và tính toán song song cùng một cách quản lý bộ nhớ về cơ bản là có thể gọi malloc. Nó là một phần của câu chuyện, nhưng không phải tất cả. Việc có thể đơn giản hóa các vấn đề liên quan đến đồng thời là sự khác biệt giữa các ngôn ngữ có khả năng tương thích tốt và các ngôn ngữ có thể đồng thời.

+0

Không. Đồng thời không song song. –

2

Về câu hỏi của bạn tại sao fork() thay vì luồng: khi bạn sử dụng các quy trình riêng biệt, bạn sẽ tự động phân tách các không gian địa chỉ.Trong các chương trình đa luồng, nó là rất phổ biến cho các chủ đề để giao tiếp bằng cách sử dụng bộ nhớ chia sẻ (tự nhiên) của chúng. Điều này rất hiệu quả, nhưng cũng khó để có được tất cả sự đồng bộ giữa các luồng, và đây là lý do tại sao một số ngôn ngữ tốt hơn đa luồng hơn các ngôn ngữ khác: chúng cung cấp các trừu tượng tốt hơn để xử lý các trường hợp thông thường giữa các luồng.

Với các quy trình riêng biệt, bạn không gặp phải các vấn đề này ở cùng mức độ. Thông thường, bạn thiết lập liên lạc giữa các quy trình để thực hiện theo một số mẫu gửi thông điệp, điều này dễ dàng hơn để có được quyền. Trên các hệ thống Unix, fork() thường rất rẻ, do đó thiết kế truyền thống của các chương trình đồng thời trong Unix sử dụng các quy trình và các đường ống để giao tiếp giữa chúng, nhưng trên các hệ thống mà quá trình tạo ra là một hoạt động đắt tiền, các luồng thường được coi là cách tiếp cận tốt hơn.

4

Trong các ngôn ngữ không được thiết kế để đồng thời, bạn phải dựa vào các cuộc gọi hệ thống cấp thấp và tự quản lý nhiều thứ. Ngược lại, một ngôn ngữ lập trình được thiết kế cho sự tương tranh, như Erlang, sẽ cung cấp các cấu trúc cấp cao che giấu các chi tiết mức thấp. Điều này làm cho nó dễ dàng hơn để lý do về tính chính xác của mã của bạn, và cũng dẫn đến nhiều mã di động hơn.

Ngoài ra, trong một ngôn ngữ lập trình được thiết kế để đồng thời, thường chỉ có một số cách để thực hiện những việc đồng thời, dẫn đến tính nhất quán. Ngược lại, nếu ngôn ngữ lập trình không được thiết kế để đồng thời, thì các thư viện khác nhau và các lập trình viên khác nhau sẽ làm mọi thứ theo nhiều cách khác nhau, làm cho việc lựa chọn cách thực hiện chúng trở nên khó khăn.

Giống như sự khác biệt giữa ngôn ngữ lập trình với bộ sưu tập rác tự động và bộ lọc không có. Nếu không có tự động hóa, lập trình viên phải suy nghĩ rất nhiều về chi tiết triển khai.

Sự khác biệt giữa lập trình đa luồng và lập trình đa tiến trình (nghĩa là fork()), là một chương trình đa luồng có thể hiệu quả hơn vì dữ liệu không phải được chuyển qua các ranh giới quy trình. có thể mạnh mẽ hơn.

2

Tôi đang nghiên cứu chủ đề (ngay bây giờ: D) và một trong những điều có vẻ như một sự khác biệt rất quan trọng về tính tương tranh giữa các ngôn ngữ là khả năng diễn đạt ngôn ngữ trên đồng thời.

Ví dụ C++ không có hỗ trợ gốc để đồng thời và nó dựa trên các chức năng do hệ điều hành cung cấp.

Java là một bước ở trên vì có một số phương pháp tích hợp trong khi các phương thức khác được để lại cho hệ điều hành (lên lịch hoặc ưu tiên ví dụ).

Thay vào đó một trong những gì có vẻ là một trong những ngôn ngữ lập trình tốt nhất hỗ trợ đồng thời là Ada trong đó có trên thực tế một tổng thể đồng thời mô hình xây dựng trong (lập kế hoạch và ưu tiên bao gồm).

Tại sao điều này quan trọng? Vì tính di động !

Sử dụng ngôn ngữ có sức mạnh diễn đạt đồng thời tốt cho phép bạn đưa chương trình đồng thời của mình lên Windows, Linux hoặc Mac với những lo ngại lớn về cách hoạt động của nó. Ví dụ: ưu tiên luồng sẽ được áp dụng trong cùng một cách trong chương trình Ada của bạn chạy trong cửa sổ, linux hoặc Mac trong khi có thể là thực sự khác nhau (bỏ qua trong một số hệ điều hành và được áp dụng cho người khác) bằng Java hoặc C++.

Đây là những gì dường như đối với tôi bởi quá trình tôi đang tham gia tại các trường đại học ngay bây giờ :)

+0

Tôi không chắc chắn ý của bạn là gì? Dường như chuẩn C++ không hỗ trợ cho các chủ đề http://stackoverflow.com/questions/218786/concurrent-programming-c – Parag

+0

Hỗ trợ cho các chủ đề đã được thêm vào C++ trong tiêu chuẩn C++ 11, được chấp nhận sau câu trả lời này đã được viết. –

0

Sự lựa chọn ngôn ngữ phụ thuộc vào ứng dụng mà bạn muốn làm.

Bạn có muốn tạo một hệ thống có khả năng mở rộng cao, với nhiều "yêu cầu" đến không? Sau đó, Erlang có thể là một lựa chọn tốt. Nó được biết là phù hợp cho các kịch bản ứng dụng "đồng thời cao".

Nếu bạn muốn viết một trò chơi điển hình và muốn sử dụng CPU lõi kép hoặc lõi tứ hiện có thường có sẵn, thì bạn sẽ bị ràng buộc với các quyết định khác nhau (khung công cụ, thư viện, giao diện phần cứng có sẵn). Trong trường hợp này, bạn sẽ sử dụng các luồng và các luồng luồng để giảm tải công việc xử lý. Có lẽ bạn sẽ sử dụng một loại hàng đợi thông điệp để giao tiếp giữa các luồng.

Phát triển web (phía máy chủ), bạn có thể đã đạt được một số kinh nghiệm về lập trình đồng thời! Có lẽ bạn đã không nhận thức được nó, bởi vì ngôn ngữ và khuôn khổ nhất định (có thể Apache & PHP) cung cấp cho bạn một môi trường lấy gánh nặng từ vai của bạn.

1

Để ngã ba là con người cho chủ đề là thiêng liêng: D

forking liên quan đến hạt nhân và tạo ra một không gian địa chỉ riêng biệt - có nghĩa proc X và Y không thể dễ dàng chia sẻ và cần phải sử dụng IPC nguyên thủy, và tạo ra một thread cho phép trong quá trình đồng bộ hóa là FAR nhanh hơn IPC trong đó liên quan đến chuyển mạch bối cảnh hạt nhân của cả hai quy trình và không cần năng suất thread (liên quan đến hạt nhân để đánh thức thread nói lên).

Tuy nhiên, có vô số lý do khiến các mô hình đồng thời khác nhau tốt hơn các mô hình khác. Tôi chỉ cung cấp cho bạn quy tắc chung về ngón tay cái cho lập trình chung. Ví dụ không forking có thể gây nguy hiểm cho logic mà có thể được tách ra bằng cách forking (Tôi yêu từ đó) - nguy cơ tuyệt chủng bởi vì nếu logic khác trong quá trình treo nó, cũng nói logic là đi xuống với quá trình này.