2012-04-02 16 views
29

Nếu bạn muốn tìm hiểu cách để sử dụng chuỗi trình thông dịch Perl, có tài liệu tốt ở perlthrtut (threads tutorial)the threads pragma manpage. Nó chắc chắn là đủ tốt để viết một số kịch bản đơn giản.Trường hợp sử dụng cho ithreads (chủ đề thông dịch viên) trong Perl và lý do để sử dụng hoặc không sử dụng chúng?

Tuy nhiên, tôi đã tìm thấy hướng dẫn nhỏ trên web trên lý do tại saonhững gì sử dụng hợp lý các chuỗi phiên dịch của Perl. Trong thực tế, không có nhiều cuộc nói chuyện về họ, và nếu mọi người nói về họ, nó khá thường xuyên để ngăn cản mọi người sử dụng chúng.

Những chủ đề, có sẵn khi perl -V:useithreadsuseithreads='define'; và tung ra bởi use threads, còn được gọi là ithreads, và có lẽ thích hợp hơn như vậy là họ rất khác biệt so với các chủ đề như được cung cấp bởi hệ điều hành Linux hoặc Windows hoặc máy ảo Java trong rằng không có gì được chia sẻ theo mặc định và thay vào đó rất nhiều dữ liệu được sao chép, không chỉ ngăn xếp luồng, do đó làm tăng đáng kể kích thước quy trình. (Để xem hiệu ứng, tải một số module trong một kịch bản kiểm tra, sau đó tạo ra chủ đề trong một vòng lặp dừng lại cho ép chính mỗi lần xung quanh, và xem tăng bộ nhớ trong task manager hoặc top.)

[...] mỗi khi bạn bắt đầu một luồng, tất cả các cấu trúc dữ liệu được sao chép vào chuỗi mới. Và khi tôi nói tất cả, ý tôi là tất cả. Ví dụ: bao gồm stashes gói, biến toàn cục, từ vựng trong phạm vi. Mọi điều!

- Things you need to know before programming Perl ithreads (Perlmonks 2003)

Khi nghiên cứu đề tài của ithreads Perl, bạn sẽ thấy mọi người ngăn cản bạn sử dụng chúng ("extremely bad idea", "fundamentally flawed", hoặc "never use ithreads for anything").

The Perl thread tutorial highlights that "Perl Threads Are Different", nhưng không cần phải giải thích cách chúng khác nhau và điều đó có ý nghĩa gì đối với người dùng.

Một lời giải thích hữu ích nhưng rất ngắn gọn về những gì ithreads thực sự là from the Coro manpage under the heading WINDOWS PROCESS EMULATION. Tác giả của mô-đun đó (Coro - các chủ đề thực sự duy nhất trong perl) cũng không khuyến khích sử dụng các trình thông dịch Perl.

Một nơi nào đó tôi đọc rằng biên dịch perl với các luồng được bật sẽ dẫn đến trình thông dịch chậm hơn đáng kể.

Có một trang Perlmonks từ năm 2003 (Things you need to know before programming Perl ithreads), trong đó tác giả hỏi: "Bây giờ bạn có thể băn khoăn tại sao các ithreads Perl không sử dụng fork()? Điều đó có ý nghĩa hơn không?" Điều này dường như đã được viết bởi tác giả của pragma forks. Bạn không chắc chắn thông tin được cung cấp trên trang đó vẫn giữ đúng vào năm 2012 cho các Perls mới hơn.

Dưới đây là một số hướng dẫn để sử dụng các chủ đề trong Perl tôi đã chắt lọc từ bài đọc của tôi (có thể sai lầm như vậy):

Cho đến nay nghiên cứu của tôi. Bây giờ, cảm ơn cho bất kỳ ánh sáng hơn bạn có thể đổ về vấn đề này của chủ đề trong Perl. Một số trường hợp sử dụng hợp lý cho ithreads trong Perl là gì? Lý do để sử dụng hoặc không sử dụng chúng là gì?

Trả lời

21

Câu trả lời ngắn gọn là chúng khá nặng (bạn không thể khởi chạy 100+ giá rẻ), và chúng thể hiện những hành vi bất ngờ (phần nào được giảm nhẹ bởi các mô-đun CPAN gần đây).

Bạn có thể sử dụng an toàn Perl ithreads bằng cách coi chúng là Actors độc lập.

  1. Tạo chủ đề :: Queue :: Any for "work".
  2. Khởi chạy nhiều ithread và hàng đợi "kết quả" đi qua chúng ("work" + own "result") Hàng đợi bằng cách đóng.
  3. Tải (yêu cầu) tất cả mã còn lại mà ứng dụng của bạn yêu cầu (không phải trước chủ đề!)
  4. Thêm công việc cho chuỗi vào Hàng đợi theo yêu cầu.

Trong "công nhân" ithreads:

  1. Mang trong bất kỳ mã chung (đối với bất kỳ loại công việc)
  2. Blocking-dequeue một phần của công việc từ Queue
  3. Nhu cầu nạp bất kỳ các phụ thuộc khác cần thiết cho tác phẩm này.
  4. Thực hiện công việc.
  5. Chuyển kết quả về chủ đề chính qua hàng đợi "kết quả".
  6. Về 2.

Nếu một số "nhân viên" chủ đề bắt đầu để có được một chút lực lưỡng, và bạn cần phải hạn chế "công nhân" chủ đề cho một số số sau đó khởi động mới ở vị trí của họ, sau đó tạo ra một " launcher "thread đầu tiên, có công việc là để khởi động" công nhân "chủ đề và móc chúng lên đến chủ đề chính.

Các vấn đề chính với tính năng này là gì?

Có một chút bất tiện với dữ liệu "được chia sẻ" khi bạn cần giải thích về việc chia sẻ (không phải là vấn đề lớn).

Bạn cần phải tìm cho ra các hành vi của các đối tượng với phương pháp DESTROY khi họ đi ra khỏi phạm vi ở một số chủ đề

The Big One (nếu họ vẫn đang yêu cầu trong một!): Dữ liệu/biến không được chia sẻ rõ ràng là CLONED thành các chuỗi mới. Đây là một hit hiệu suất và có lẽ không phải ở tất cả những gì bạn dự định. Các công việc xung quanh là để khởi động ithreads từ một điều kiện khá "nguyên sơ" (không có nhiều mô-đun được nạp).

IIRC, có các mô-đun trong Threads :: namespace giúp giúp phụ thuộc rõ ràng và/hoặc làm sạch dữ liệu nhân bản cho các chuỗi mới.

Ngoài ra, IIRC, có một mô hình hơi khác với các chủ đề "Căn hộ", được thực hiện bởi Thread :: Appartment có mẫu sử dụng khác và một bộ cân bằng khác.

Kết quả cuối cùng:

Đừng sử dụng chúng trừ khi bạn biết mình đang làm gì :-)

Fork thể hiệu quả hơn trên Unix, nhưng những câu chuyện IPC là nhiều đơn giản hơn cho ithreads. (Điều này có thể đã được giảm nhẹ bởi các mô-đun CPAN kể từ lần cuối tôi nhìn :-)

Chúng là vẫn còn tốt hơn so với chỉ của Python.

Có thể, một ngày nào đó, là cái gì đó tốt hơn nhiều trong Perl 6.

+0

Cảm ơn! Đây là hướng dẫn sử dụng chi tiết nhất cho các chủ đề của Perl mà tôi đã thấy cho đến nay. - Trong câu hỏi của tôi, tôi đã nói rằng * cách * sử dụng ithreads được bao phủ trong khi * tại sao * và * những gì cho * thiếu. Suy nghĩ thêm về điều này, * how *, the * why *, và * what for * liên quan chặt chẽ, và thực sự * cách * không đủ chính xác (đối với những người dùng Perl thông thường như tôi) để trả lời * tại sao * và * cái gì cho *. - Câu trả lời này là một bước tiến. Cảm ơn một lần nữa. – Lumi

+0

"Chúng vẫn tốt hơn chủ đề của Python." - Bạn có thể giải thích điều này? Xin vui lòng, nó rất intresting – nordicdyno

+3

Chủ yếu là nó về GIL Python trong hầu hết các triển khai (chủ yếu là cpython nhưng những người khác để ít hơn extents). Về cơ bản, nó có nghĩa là các luồng hệ điều hành trên Python không thể thực thi đồng thời công việc của CPU - điều này hoàn toàn đánh bại điểm của chúng. Bạn có thể sử dụng chúng (các chủ đề Python) để làm cho I/O đồng bộ hơn một chút, nhưng nó đơn giản hơn để sử dụng các API hướng sự kiện để làm điều đó. –

8

Tôi đã sử dụng "bài" perl của nhiều lần. Chúng hữu ích nhất để khởi chạy một số quy trình và tiếp tục với một thứ khác. Tôi không có nhiều kinh nghiệm trong lý thuyết về cách họ làm việc dưới mui xe, nhưng tôi có rất nhiều kinh nghiệm viết mã thực tế với họ.

Ví dụ: tôi có chuỗi máy chủ lắng nghe các kết nối mạng đến và kích hoạt phản hồi trạng thái khi ai đó yêu cầu. Tôi tạo chủ đề đó, sau đó chuyển sang và tạo một chuỗi khác theo dõi hệ thống, kiểm tra năm mục, ngủ một vài giây và lặp lại. Có thể mất 3-4 giây để thu thập dữ liệu giám sát, sau đó nó được đẩy vào biến được chia sẻ và luồng máy chủ có thể đọc khi cần và ngay lập tức trả lại kết quả đã biết cuối cùng cho bất kỳ ai yêu cầu. Các chủ đề màn hình, khi nó thấy rằng một mục là ở trạng thái xấu, đá ra một chủ đề riêng biệt để sửa chữa mục đó. Sau đó, nó di chuyển trên, kiểm tra các mục khác trong khi một trong những xấu được sửa chữa, và đá ra các chủ đề khác cho các mục xấu hoặc tham gia hoàn thành sửa chữa chủ đề. Các chương trình chính tất cả các trong khi là looping mỗi vài giây, đảm bảo rằng các chủ đề màn hình và máy chủ không thể join/vẫn chạy. Tất cả điều này có thể được viết như là một bó của các chương trình riêng biệt sử dụng một số hình thức khác của IPC, nhưng chủ đề của perl làm cho nó đơn giản.

Một địa điểm khác mà tôi đã sử dụng chúng là máy phát điện fractal. Tôi sẽ chia nhỏ các phần của hình ảnh bằng cách sử dụng một số thuật toán và sau đó khởi động như nhiều chủ đề như tôi có CPU để làm công việc. Họ muốn mỗi công cụ kết quả của họ vào một đối tượng GD duy nhất, mà không gây ra vấn đề bởi vì họ từng làm việc trên các phần khác nhau của mảng, và sau đó khi thực hiện tôi sẽ viết ra hình ảnh GD. Đó là giới thiệu của tôi để sử dụng các chủ đề perl, và là một giới thiệu tốt, nhưng sau đó tôi viết lại nó trong C và nó đã được hai đơn đặt hàng của cường độ nhanh hơn :-). Sau đó, tôi viết lại phiên bản ren của tôi để sử dụng Inline :: C, và nó chỉ chậm hơn 20% so với phiên bản C thuần túy. Tuy nhiên, trong hầu hết các trường hợp mà bạn muốn sử dụng các chủ đề do là CPU chuyên sâu, bạn có thể muốn chỉ cần chọn một ngôn ngữ khác.

Như đã đề cập bởi những người khác, ngã ba và chủ đề thực sự trùng lặp cho nhiều mục đích. Tuy nhiên, Coro không thực sự cho phép sử dụng nhiều CPU hoặc xử lý song song như fork và thread, bạn sẽ chỉ thấy quá trình của mình bằng 100%. Tôi quá đơn giản hóa điều này, nhưng tôi nghĩ cách dễ nhất để mô tả Coro là nó là một bộ lập lịch biểu cho các chương trình con của bạn. Nếu bạn có một chương trình con chặn bạn có thể nhảy đến một cái khác và làm điều gì đó khác trong khi chờ đợi, ví dụ bạn có một ứng dụng tính toán kết quả và ghi chúng vào một tập tin. Một khối có thể tính toán kết quả và đẩy chúng vào một kênh. Khi nó hết công việc, một khối khác bắt đầu ghi chúng vào đĩa. Trong khi khối đó đang chờ trên đĩa, khối khác có thể bắt đầu tính toán kết quả lại nếu nó hoạt động nhiều hơn. Phải thừa nhận rằng tôi đã không làm được nhiều với Coro; Nghe có vẻ như là một cách hay để tăng tốc một số thứ, nhưng tôi có chút khó khăn khi không thể làm hai việc cùng một lúc.

Sở thích cá nhân của riêng tôi nếu tôi muốn thực hiện đa xử lý là sử dụng ngã ba nếu tôi đang thực hiện rất nhiều thứ nhỏ hoặc ngắn, chủ đề cho một số lượng lớn hoặc những thứ tồn tại lâu dài.

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