Lập trình đa luồng trong PHP với Dịch Pthreads. Tính toán đa luồng trong PHP: pthreads của chuỗi thảo luận Insane php

Mẹ của người bạn tốt của tôi bị mất va li trên chuyến bay từ St.Petersburg đến Moscow, và bà ấy đã có một chuyến bay xa hơn đến những bờ biển ấm áp, và bây giờ bà ấy đã ở khu nghỉ mát - không có áo tắm, dép và với một chiếc áo phông trên tay. Hành lý. Từ trí nhớ cũ, tôi đã cho cô ấy một vài mẹo về những việc phải làm và nên chạy ở đâu, và hôm nay tôi quyết định viết tất cả những gì tôi biết về một chủ đề nhất định ở đây.

Để làm rõ lý do tại sao tôi thông minh như vậy, hãy để tôi nhắc bạn rằng đã có lần tôi làm việc trong lĩnh vực xử lý mặt đất của một số hãng hàng không và trong số những việc khác, xử lý một số vấn đề liên quan đến truy tìm hành lý. Tất nhiên, cộng với kinh nghiệm của riêng tôi về các chuyến bay. Tuy nhiên, kể từ Tôi đã rời dịch vụ hàng không một vài năm trước, có lẽ một số sắc thái có thể đã thay đổi - nếu vậy, tôi sẽ biết ơn các ý kiến ​​về chủ đề và sửa thông tin trong bài đăng.

Tôi sẽ bắt đầu bằng cách nói những gì bạn cần làm để hành lý của bạn KHÔNG bị thất lạc:
1. Xé tất cả các thẻ và nhãn dán từ các chuyến đi trước khỏi vali, ngay cả những thẻ nhỏ có mã vạch, thường được dán riêng vào vali - chúng có thể gây nhầm lẫn cho hệ thống tự động quét và phân loại hành lý.
2. Treo thẻ tên trên vali của bạn (túi, hộp, gói - nói chung là mọi thứ bạn làm thủ tục): bạn có thể mua trước tùy chọn có thể tái sử dụng hoặc mang thẻ giấy tại quầy làm thủ tục - thường là tất cả các hãng hàng không. cung cấp cho họ mà không có hạn chế ... Và Emirates, ví dụ, thường có các thẻ nhựa tuyệt vời trên một sợi dây chắc chắn có thể tồn tại trong một thời gian rất dài:

Những người hoang tưởng cũ có thể làm như tôi: Tôi luôn có một thẻ nhựa có thể tái sử dụng từ bộ Samsonite với địa chỉ nhà thường trú, số điện thoại và e-mail trên vali của tôi và khi tôi bay đi đâu đó trong kỳ nghỉ, tôi cũng treo một thẻ giấy vào mà tôi cho biết ngày lưu trú tại một nơi mới và tất cả các liên hệ có thể có (tên và địa chỉ của khách sạn, số điện thoại địa phương, nếu có, và tất nhiên là họ và tên của bạn).
3. Tại quầy làm thủ tục, hãy đảm bảo rằng thẻ hành lý được in bởi đại lý làm thủ tục, với mã thành phố của thành phố bạn bay đến và số hiệu chuyến bay, được dán vào hành lý của bạn.
4. Nếu bạn có nhiều chuyến bay nối chuyến, vui lòng thông báo cho đại lý làm thủ tục và nêu rõ bạn muốn ký gửi hành lý ở điểm nào. Trong một số trường hợp, hành lý sẽ phải được nhận tại sân bay này hoặc sân bay khác trên đường đi, bất kể bạn muốn gì: điều này áp dụng, ví dụ: vận chuyển giữa các sân bay ("Orly" và "Charles de Gaulle" ở Paris, "Domodedovo" - "Sheremetyevo" - "Vnukovo" ở Moscow), các nhà ga riêng (nhà ga 1 và 2 ở Frankfurt) hoặc tại điểm đến đầu tiên ở Hoa Kỳ hoặc Mexico - đây là yêu cầu của hải quan ở các quốc gia này: giả sử bạn đang bay Moscow -Washington-Phoenix, thẻ hành lý được cấp cho cả ba chặng đến Phoenix, nhưng ở Washington, hành lý của bạn sẽ cần phải được thu gom thực tế, làm thủ tục hải quan và sau đó gửi trở lại. Ngoài ra, nếu bạn đang làm thủ tục trên xe đẩy bạn được phép mang lên máy bay, hoặc một con vật, bạn có thể phải nhận nó tại điểm trung chuyển. Nói chung, trong trường hợp đường bay khó chuyển, tốt hơn hết bạn nên làm rõ trước các sắc thái chuyển động của hành lý trong tổng đài của hãng hàng không hoặc trong trường hợp đặc biệt, khi làm thủ tục.
5. Làm cho hành lý của bạn có thể nhìn thấy được: không phải lúc nào các động cơ hoặc lỗi trong hệ thống phân loại cũng là nguyên nhân gây ra sự chậm trễ của hành lý. Đôi khi, một hành khách khác đang mất tập trung, mệt mỏi sau một chuyến bay dài, sẽ lấy từ thắt lưng hành lý chiếc túi thể thao màu đen hoặc đen giống như của bạn. Do đó, hãy đánh dấu hành lý của bạn: treo một loạt ruy băng sáng màu hoặc một món đồ chơi mềm nhỏ trên tay cầm, dán một miếng dán lớn lên đó, hoặc chỉ ở giai đoạn chọn vali, hãy ưu tiên một màu sắc khác thường.

Những gì không nên ký gửi trong hành lý?
Hãy nhớ rằng, tất cả các hãng hàng không và sân bay bị mất hành lý. Tất nhiên, số liệu thống kê là khác nhau đối với tất cả mọi người, nhưng ngay cả những hãng hàng không đáng tin cậy nhất và ngay cả sân bay nhỏ nhất, nơi một người bốc xếp sẽ đi xe đẩy với vali trực tiếp từ quầy làm thủ tục lên máy bay, có thể bị thất lạc hoặc chậm trễ hành lý. Vì vậy, tôi khuyên bạn nên luôn mang theo hành lý xách tay:
- các giấy tờ quan trọng, kể cả những giấy tờ không cần thiết trong chuyến bay (ví dụ: trong chuyến đi cuối cùng đến St.Petersburg, tôi cần đổi bằng lái, và tôi đã mang theo giấy đăng ký kết hôn và tất cả các loại thẻ từ một trường dạy lái xe trong người. hành lý xách tay)
- khóa (kết hợp với thẻ có địa chỉ của bạn, điều này có thể nguy hiểm)
- tiền, đồ trang sức (không có bình luận)
- thiết bị dễ vỡ đắt tiền
- các loại thuốc bạn thường dùng, với số lượng cần thiết cho chuyến bay, và với một khoản chênh lệch nhỏ trong trường hợp bạn phải tìm một chất tương tự ở một quốc gia hoặc thành phố nước ngoài. Thuốc theo toa sẽ không thể mua trong trường hợp mất hành lý, hãy mang theo với số lượng cần thiết cho toàn bộ chuyến đi.
- những gì bạn có thể cần gấp khi đến nơi (ví dụ: bộ sạc điện thoại
- một thứ có giá trị tình cảm đối với cá nhân bạn: đôi khi hành lý bị thất lạc không thể lấy lại được, và nếu việc đánh mất cuốn nhật ký cá nhân khiến trái tim bạn tan nát, tốt hơn là bạn nên để nó ở nhà hoặc mang theo trên máy bay

Một câu chuyện mang tính hướng dẫn: trong thời gian làm việc của tôi ở St.Petersburg Lufthansa, một cặp vợ chồng từ Hoa Kỳ đến văn phòng của chúng tôi vắt tay - hành lý của họ, trong đó có những tài liệu rất quan trọng cho vụ kiện nhận con nuôi, đã không đến nơi, tòa án là người tiếp theo. ngày. Tất nhiên, hãng hàng không phải chịu trách nhiệm về việc mất hành lý, nhưng ai là người nhận được điều đó tốt hơn? Để tránh trường hợp như vậy, bạn chỉ cần để những giấy tờ quan trọng trong hành lý xách tay là đủ.

Vì vậy, bạn đã đến nơi và không tìm thấy hành lý của mình trên dây đai hành lý. Để làm gì?
1. Nếu bạn đã kiểm tra thứ gì đó không phải là vali thông thường: ván trượt, đàn cello, TV plasma toàn tường, xe nôi, con chó cẩm thạch sống, hãy kiểm tra xem có điểm thu gom riêng cho cái gọi là không. Hành lý quá khổ hoặc Hành lý cồng kềnh - hành lý, giống như hành lý tôi đã mô tả ở trên, thường được chất vào một ngăn riêng và cũng được bốc dỡ riêng theo cách thủ công. Nếu hành lý của bạn không được tìm thấy ở đó
2. Đến quầy truy tìm hành lý hoặc Lost & Found. Tại đó, bạn sẽ cần điền vào một mẫu đơn đặc biệt với thông tin chi tiết về hành lý của mình: lộ trình, diện mạo, danh sách ngắn nội dung, địa chỉ liên lạc của bạn tại nơi thường trú và thời gian tạm trú. Ngoài ra, trong dịch vụ truy tìm hành lý, bạn rất có thể sẽ thấy biểu đồ hành lý này:

Theo cách phân loại này, hành lý thất lạc của bạn sẽ được mã hóa và để bạn hiểu, hai vali này sẽ được mã hóa theo cùng một cách:

Vì vậy, hãy thoải mái thêm các chi tiết bổ sung trong mô tả và đừng bỏ qua đoạn nội dung. Theo quy định, khi điền vào báo cáo hành lý chậm trễ lần đầu, bạn sẽ được yêu cầu chỉ ra một số mục nội dung mà hành lý của bạn có thể được nhận dạng nếu không có dấu hiệu nhận biết bên ngoài và hành lý sẽ phải được mở (nếu túi được mở, nó sẽ được đặt bên trong thông báo về điều này). Ví dụ xấu: áo phông / sách / khăn ướt, ví dụ tốt: bộ bikini màu đỏ tươi / Catalogue tái sản xuất Malevich / bàn ủi gấp. Sau khi điền đơn, nhân viên truy tìm hành lý sẽ cung cấp cho bạn một số ở định dạng XXXYY11111, trong đó XXX là mã sân bay đến, YY là mã hãng hàng không đến + 5 chữ số của số sê-ri ứng dụng: ví dụ: JFKLH12345, nếu bạn đã đến với Lufthansa tại Sân bay Kennedy ở New York. Hãy nhớ hoặc ghi lại số này - đó sẽ là cách dễ nhất để tìm thấy ứng dụng của bạn trên đó với các yêu cầu khác.
Bằng cùng một số, bạn có thể kiểm tra trạng thái mong muốn CHÍNH MÌNH (liên kết vì một lý do nào đó bay: nếu nó không hoạt động với bạn, hãy google World Tracer Online và theo nghĩa đen là liên kết thứ hai - với tiêu đề Truy tìm hành lý trên trang web worldtracer.aero - là những gì bạn cần), bởi vì nó thường rất khó khăn để vượt qua bị mất và được tìm thấy
3. Cố gắng liên hệ với văn phòng hãng hàng không của bạn tại sân bay đến: đôi khi (tôi nhấn mạnh - XIN LỖI!) Trong trường hợp bạn đến không phải về nhà, nhưng đến một nơi tạm trú (đi nghỉ, đi công tác), hãng hàng không có thể cung cấp một bộ đồ dùng vệ sinh cá nhân (Lufthansa đã bao gồm một chiếc áo phông ngoại cỡ, bàn chải đánh răng và kem đánh răng, lược, gói nhỏ dầu gội và sữa tắm, một túi bột giặt, v.v.) hoặc thanh toán bằng tiền mặt cho các chi phí nhỏ tại chỗ (thanh toán tiền mặt giao ngay).

Chuyện gì sẽ xảy ra tiếp theo?
Hồ sơ của bạn (cái gọi là AHL) sẽ được chuyển đến hệ thống tìm kiếm hành lý tập trung (World Tracer). Tất cả các vật phẩm hành lý không có người nhận đều nằm trong cùng một hệ thống tìm kiếm, không quan trọng là chúng được tìm thấy mà không có thẻ ở đường sau của bãi gửi hành lý hay vẫn còn trên đai hành lý, mỗi vật phẩm này cũng nhận được một tệp có định dạng XXXYY11111, chỉ của một phân loài khác - cái gọi là. báo cáo trên tay hoặc OHD. Nếu dữ liệu từ các tệp AHL và OHD trùng khớp (tên, mô tả về va li, tuyến đường, v.v.), cả hai nhà ga (nơi họ thông báo mất hành lý và nơi tìm thấy hành lý không có người nhận) sẽ nhận được thông báo, và sau đó câu hỏi về công nghệ: kiểm tra lại và chuyển hành lý đến thành phố mong muốn có thành công hay không. Tất nhiên, cũng phải thực hiện nhiều thao tác thủ công - nhắn tin, từ chối những chiếc vali tương tự nhưng không giống nhau, cộng với việc trả lời nhiều cuộc điện thoại - nói chung nhân viên dịch vụ truy tìm hành lý không phải ngán ngẩm.
Thống kê gần đúng: hơn 90% hành lý thất lạc được tìm thấy trong 3 ngày đầu tìm kiếm, 3% bị thất lạc mãi mãi.
Bạn có thể làm gì?
1. Nếu bạn phải mua bất cứ thứ gì cần gấp khi đến nơi (từ bàn chải đánh răng đến bộ đồ công sở), hãy nhớ giữ lại biên lai của bạn để được hoàn trả trong tương lai. Tuy nhiên, việc mua hàng đắt tiền không cần thiết phải bỏ, tại sao - tôi sẽ giải thích ở phần sau.
2. Trên hành trình mới, hãy lập danh sách nội dung chi tiết nhất, tốt nhất là có màu sắc, nhãn hiệu và chi phí gần đúng của từng mặt hàng, lý tưởng là bằng tiếng Anh (nếu không, nhân viên hàng không sẽ phải dịch danh sách này để nhập vào hệ thống), liên hệ với hãng hàng không và gửi cho họ danh sách này, nó sẽ được thêm vào tuyên bố truy tìm hành lý. Trong 5 ngày đầu tiên, sân bay đến thực hiện việc tìm kiếm hành lý, sau đó việc tìm kiếm sẽ đến với hãng hàng không vận chuyển (hãng hàng không được nêu trong số đơn đăng ký - nhớ JFKLH12345?), Và sau 21 ngày, bạn có thể nộp đơn xin cuối cùng. đền bù.
3. Nếu sau 21 ngày kể từ ngày nộp đơn yêu cầu mất hành lý mà không tìm thấy thì liên hệ với hãng vận chuyển để yêu cầu bồi thường. Nếu tôi không nhầm, thời hạn là 2 năm, tức là Bạn có thể nộp đơn yêu cầu bồi thường trong vòng hai năm kể từ ngày bạn nộp đơn yêu cầu bồi thường tổn thất.

Thanh toán tiền bồi thường.
Để thanh toán bồi thường, bạn sẽ cần liên hệ với văn phòng đại diện của hãng hàng không để cung cấp đơn yêu cầu thanh toán, các giấy tờ xác nhận chuyến bay và thông tin về việc mất hành lý (thẻ lên máy bay, thẻ hành lý, số báo cáo thất lạc hành lý, chi tiết thanh toán). Nếu tôi không nhầm, ở Liên bang Nga, quyết định về việc bồi thường phải được xem xét hợp pháp trong vòng 30 ngày. Bạn cũng có thể được yêu cầu ước tính chi phí của đồ đạc và nếu có thể, hãy cung cấp biên lai mua vali và những thứ trong đó (tôi hiểu rằng điều này là không thực tế trong hầu hết các trường hợp, nhưng đây là một phần của thủ tục).
Trước đây, các khoản thanh toán được thực hiện dựa trên trọng lượng của hành lý ký gửi - khoảng $ 20 mỗi kg. Sau đó, hệ thống thanh toán đã được thay đổi và trách nhiệm của các hãng hàng không bị giới hạn ở số lượng 1000 đơn vị thông thường (chi phí của một đơn vị thông thường được tính trong hãng hàng không), tại thời điểm làm việc của tôi tương ứng với khoảng 1300 euro. Những thứ kia. ngay cả khi bạn mang theo séc để mua vali của Louis Vuitton, được làm từ hàng ngàn tấm da tắc kè Bolivia và được nhồi kim cương, bạn sẽ không nhận được nhiều hơn 1.300 euro.

Có vẻ như các nhà phát triển PHP hiếm khi sử dụng đồng thời. Tôi sẽ không nói về sự đơn giản của mã đồng bộ, lập trình đơn luồng tất nhiên là đơn giản hơn và rõ ràng hơn, nhưng đôi khi một việc sử dụng song song nhỏ có thể mang lại sự gia tăng hữu hình về hiệu suất.

Trong bài viết này, chúng ta sẽ xem xét cách đa luồng có thể đạt được trong PHP bằng cách sử dụng phần mở rộng pthreads. Điều này sẽ yêu cầu cài đặt ZTS (Zend Thread Safety) PHP 7.x, cùng với phần mở rộng pthreads v3 được cài đặt. (Tại thời điểm viết bài này, trong PHP 7.1, người dùng sẽ cần cài đặt từ nhánh chính trong kho lưu trữ pthreads - xem phần mở rộng của bên thứ ba.)

Làm rõ một chút: pthreads v2 dành cho PHP 5.x và không còn được hỗ trợ, pthreads v3 dành cho PHP 7.x và đang được phát triển tích cực.

Sau khi lạc đề như vậy, hãy bắt tay vào kinh doanh ngay thôi!

Xử lý các tác vụ một lần

Đôi khi bạn muốn xử lý các tác vụ một lần theo cách đa luồng (ví dụ: thực hiện một số tác vụ gắn với I / O). Trong những trường hợp như vậy, bạn có thể sử dụng lớp Thread để tạo một luồng mới và bắt đầu một số xử lý trong một luồng riêng biệt.

Ví dụ:

$ task = new class expand Chủ đề (private $ response; public function run () ($ content = file_get_contents ("http://google.com"); preg_match ("~ (.+)~ ", $ content, $ match); $ this-> response = $ match;)); $ task-> start () && $ task-> join (); var_dump ($ task-> response); // string (6) "Google"

Ở đây, phương thức chạy là quá trình xử lý của chúng tôi, sẽ được thực hiện bên trong luồng mới. Khi Thread :: start được gọi, một luồng mới được tạo ra và phương thức run được gọi. Sau đó, chúng tôi đính kèm luồng sinh sản trở lại luồng chính bằng cách gọi Thread :: join, sẽ chặn cho đến khi luồng sinh sản hoàn tất quá trình thực thi. Điều này đảm bảo rằng nhiệm vụ hoàn thành trước khi chúng tôi cố gắng xuất ra kết quả (được lưu trữ trong $ task-> response).

Có thể không mong muốn gây ô nhiễm lớp với các trách nhiệm bổ sung liên quan đến logic luồng (bao gồm cả trách nhiệm xác định phương thức chạy). Chúng ta có thể phân biệt các lớp như vậy bằng cách kế thừa chúng từ lớp Threaded. Sau đó, chúng có thể được bắt đầu bên trong một chuỗi khác:

Nhiệm vụ lớp mở rộng Threaded (public $ response; public function someWork () ($ content = file_get_contents ("http://google.com"); preg_match ("~ (. +) ~", $ Content, $ so khớp); $ this-> response = $ match;)) $ task = new Task; $ thread = new class ($ task) mở rộng Thread (private $ task; public function __construct (Threaded $ task) ($ this-> task = $ task;) public function run () ($ this-> task-> someWork ( );)); $ thread-> start () && $ thread-> join (); var_dump ($ task-> response);

Bất kỳ lớp nào cần được chạy trên một chuỗi riêng biệt, Nên kế thừa từ lớp Threaded. Điều này là do nó cung cấp các khả năng cần thiết để thực hiện xử lý trên các luồng khác nhau, cũng như bảo mật ngầm và các giao diện hữu ích (chẳng hạn như đồng bộ hóa tài nguyên).

Chúng ta hãy xem xét hệ thống phân cấp lớp được cung cấp bởi phần mở rộng pthreads:

Threaded (thực hiện có thể truyền qua, có thể thu thập) Thread Worker dễ bay hơi

Chúng ta đã trình bày và tìm hiểu những kiến ​​thức cơ bản về các lớp Thread và Threaded, bây giờ chúng ta hãy xem xét ba lớp còn lại (Worker, Volatile và Pool).

Sử dụng lại các luồng

Việc bắt đầu một luồng mới cho mỗi tác vụ cần được thực hiện song song sẽ rất tốn kém. Điều này là do kiến ​​trúc "không có gì chung" phải được triển khai trong pthreads để đạt được đa luồng trong PHP. Điều đó có nghĩa là toàn bộ ngữ cảnh thực thi của phiên bản trình thông dịch PHP hiện tại (bao gồm mọi lớp, giao diện, đặc điểm và chức năng) phải được sao chép cho mọi luồng được tạo. Vì điều này có tác động đáng kể đến hiệu suất, luồng phải luôn được sử dụng lại bất cứ khi nào có thể. Luồng có thể được sử dụng lại theo hai cách: sử dụng Công nhân hoặc sử dụng Hồ bơi.

Lớp Worker được sử dụng để thực hiện đồng bộ một số tác vụ trong một luồng khác. Điều này được thực hiện bằng cách tạo một phiên bản Worker mới (tạo một luồng mới) và sau đó đẩy các tác vụ lên ngăn xếp của luồng riêng biệt đó (sử dụng Worker :: stack).

Đây là một ví dụ nhỏ:

Nhiệm vụ lớp mở rộng Threaded (private $ value; public function __construct (int $ i) ($ this-> value = $ i;) public function run () (usleep (250000); echo "Tác vụ: ($ this-> value) \ n ";)) $ worker = new Worker (); $ worker-> start (); for ($ i = 0; $ i stack (Tác vụ mới ($ i));) while ($ worker-> collect ()); $ worker-> shutdown ();

Trong ví dụ trên, 15 tác vụ được đẩy lên ngăn xếp cho đối tượng $ worker mới thông qua phương thức Worker :: stack, và sau đó được xử lý theo thứ tự chúng được đẩy. Phương thức Worker :: collect, như được hiển thị ở trên, được sử dụng để dọn dẹp các tác vụ ngay sau khi chúng hoàn thành việc thực thi. Sử dụng nó bên trong vòng lặp while, chúng tôi chặn luồng chính cho đến khi tất cả các tác vụ từ ngăn xếp đã hoàn thành và cho đến khi chúng được dọn dẹp - trước khi chúng tôi gọi Worker :: shutdown. Việc chấm dứt nhân viên trước thời hạn (tức là trong khi vẫn còn các nhiệm vụ cần hoàn thành) sẽ vẫn chặn luồng chính cho đến khi tất cả các tác vụ đã hoàn thành việc thực thi, chỉ là các tác vụ sẽ không được dọn dẹp bởi bộ thu gom rác (điều này đòi hỏi bộ nhớ rò rỉ).

Lớp Worker cung cấp một số phương thức khác liên quan đến ngăn xếp tác vụ của nó, bao gồm Worker :: unack để loại bỏ tác vụ được thêm cuối cùng và Worker :: getStacked để lấy số tác vụ trên ngăn xếp thực thi. Ngăn xếp của công nhân chỉ chứa các nhiệm vụ cần được hoàn thành. Khi một nhiệm vụ đã được hoàn thành từ ngăn xếp, nó sẽ được gỡ bỏ và đặt trên một ngăn xếp (nội bộ) riêng biệt để thu gom rác (sử dụng phương thức Worker :: collect).

Một cách khác để sử dụng lại một luồng cho nhiều tác vụ là sử dụng một nhóm luồng (thông qua lớp Pool). Nhóm luồng sử dụng một nhóm Công nhân để cho phép thực hiện các tác vụ đồng thời, trong đó yếu tố đồng thời (số luồng nhóm mà nó hoạt động) được đặt khi nhóm được tạo.

Hãy điều chỉnh ví dụ trên để sử dụng một nhóm công nhân:

Tác vụ lớp mở rộng Threaded (private $ value; public function __construct (int $ i) ($ this-> value = $ i;) public function run () (usleep (250000); echo "Tác vụ: ($ this-> value) \ n ";)) $ pool = new Pool (4); for ($ i = 0; $ i submit (Tác vụ mới ($ i)));) while ($ pool-> collect ()); $ pool-> shutdown ();

Có một số khác biệt đáng chú ý khi sử dụng pool so với worker. Đầu tiên, pool không cần phải được khởi động theo cách thủ công; nó bắt đầu thực hiện các tác vụ ngay khi có sẵn. Thứ hai, chúng tôi gửi nhiệm vụ đối với nhóm, không phải đặt chúng trên ngăn xếp... Ngoài ra, lớp Pool không kế thừa từ Threaded và do đó không thể được truyền cho các luồng khác (không giống như Worker).

Như một thông lệ tốt, đối với công nhân và hồ bơi, bạn nên luôn dọn dẹp công việc của họ ngay sau khi họ hoàn thành và sau đó tự chấm dứt công việc đó theo cách thủ công. Các luồng được tạo bằng cách sử dụng lớp Thread cũng phải được gắn vào luồng cha.

pthreads và (không) khả biến

Lớp cuối cùng mà chúng ta sẽ đề cập đến là Volatile, một bổ sung mới cho pthreads v3. Khái niệm về tính bất biến đã trở thành một khái niệm quan trọng trong pthreads, vì nếu không có nó, hiệu suất sẽ giảm đáng kể. Do đó, theo mặc định, các thuộc tính của các lớp Threaded, bản thân nó là các đối tượng Threaded, bây giờ là bất biến và do đó không thể bị ghi đè sau lần gán ban đầu của chúng. Khả năng thay đổi rõ ràng cho các thuộc tính như vậy hiện đang được ưu tiên và vẫn có thể đạt được với lớp Volatile mới.

Hãy xem một ví dụ minh họa các ràng buộc về tính bất biến mới:

Tác vụ lớp mở rộng Luồng // một lớp Luồng (hàm public __construct () ($ this-> data = new Threaded (); // $ this-> dữ liệu không được ghi đè, vì nó là thuộc tính Luồng của một lớp Luồng)) $ task = new class (new Task ()) mở rộng Thread (// một lớp Threaded, vì Thread mở rộng chức năng công khai của Threaded __construct ($ tm) ($ this-> threadedMember = $ tm; var_dump ($ this-> threadedMember-> data); // object (Threaded) # 3 (0) () $ this-> threadedMember = new StdClass (); // không hợp lệ, vì thuộc tính là thành viên Threaded của một lớp Threaded));

Mặt khác, các thuộc tính luồng của các lớp dễ bay hơi, có thể thay đổi:

Class Task mở rộng Volatile (public function __construct () ($ this-> data = new Threaded (); $ this-> data = new StdClass (); // hợp lệ, vì chúng ta đang ở trong một lớp dễ bay hơi)) $ task = new class (new Task ()) mở rộng Thread (public function __construct ($ vm) ($ this-> flightMember = $ vm; var_dump ($ this-> flightMember-> data); // object (stdClass) # 4 (0) () // vẫn không hợp lệ, vì Volatile mở rộng Threaded, vì vậy thuộc tính vẫn là thành viên Threaded của một lớp Threaded $ this-> flightMember = new StdClass ();));

Chúng ta có thể thấy rằng lớp Volatile ghi đè tính bất biến được áp đặt bởi lớp Threaded cha để cung cấp khả năng thay đổi các thuộc tính của Threaded (cũng như unset ()).

Có một chủ đề thảo luận nữa là chủ đề về sự đột biến và lớp Biến đổi - mảng. Trong pthreads, mảng sẽ tự động được truyền tới các đối tượng dễ bay hơi khi được gán cho một thuộc tính của lớp Threaded. Điều này là do không an toàn khi thao tác một mảng từ nhiều ngữ cảnh PHP.

Hãy xem lại ví dụ để hiểu rõ hơn một số điều:

$ mảng =; $ task = new class ($ array) mở rộng Thread (private $ data; public function __construct (array $ array) ($ this-> data = $ array;) public function run () ($ this-> data = 4; $ this-> data = 5; print_r ($ this-> data);)); $ task-> start () && $ task-> join (); / * Đầu ra: Vật thể bay hơi (=> 1 => 2 => 3 => 4 => 5) * /

Chúng ta có thể thấy rằng các đối tượng dễ bay hơi có thể được coi như thể chúng là mảng, vì chúng hỗ trợ các phép toán mảng như (như hình trên) toán tử tập con (). Tuy nhiên, các lớp Volatile không hỗ trợ các hàm mảng cơ bản như array_pop và array_shift. Thay vào đó, lớp Threaded cung cấp cho chúng ta các hoạt động tương tự như các phương thức tích hợp sẵn.

Như một minh chứng:

$ data = lớp mới mở rộng Biến động (public $ a = 1; public $ b = 2; public $ c = 3;); var_dump ($ data); var_dump ($ data-> pop ()); var_dump ($ data-> shift ()); var_dump ($ data); / * Đầu ra: object ( [email được bảo vệ]) # 1 (3) (["a"] => int (1) ["b"] => int (2) ["c"] => int (3)) int (3) int (1) đối tượng ( [email được bảo vệ]) # 1 (1) (["b"] => int (2)) * /

Các hoạt động được hỗ trợ khác bao gồm Threaded :: chunk và Threaded :: merge.

Đồng bộ hóa

Trong phần cuối cùng của bài viết này, chúng ta sẽ xem xét đồng bộ hóa trong pthreads. Đồng bộ hóa là một kỹ thuật cho phép bạn kiểm soát quyền truy cập vào các tài nguyên được chia sẻ.

Ví dụ: hãy triển khai một bộ đếm đơn giản:

$ counter = lớp mới mở rộng Thread (public $ i = 0; public function run () (for ($ i = 0; $ i i;))); $ counter-> start (); for ($ i = 0; $ i i;) $ counter-> join (); var_dump ($ counter-> i); // sẽ in ra một số từ 10 đến 20

Nếu không sử dụng đồng bộ hóa, đầu ra không xác định. Nhiều luồng ghi vào cùng một biến mà không có quyền truy cập được kiểm soát, có nghĩa là các bản cập nhật sẽ bị mất.

Hãy sửa lỗi này để chúng tôi nhận được đầu ra chính xác 20 bằng cách thêm đồng bộ hóa:

$ counter = lớp mới mở rộng Thread (public $ i = 0; public function run () ($ this-> sync (function () (for ($ i = 0; $ i i;)));)); $ counter-> start (); $ counter-> sync (function ($ counter) (for ($ i = 0; $ i i;)), $ counter); $ counter-> join (); var_dump ($ counter-> i); // int (20)

Các khối mã được đồng bộ hóa cũng có thể tương tác với nhau bằng các phương thức Threaded :: wait và Threaded :: allow (hoặc Threaded :: allowAll).

Đây là mức tăng tuần tự trong hai vòng lặp while được đồng bộ hóa:

$ counter = new class expand Chủ đề (public $ cond = 1; public function run () ($ this-> sync (function () (for ($ i = 0; $ i notification (); if ($ this-> cond === 1) ($ this-> cond = 2; $ this-> wait ();))));)); $ counter-> start (); $ counter-> sync (function ($ counter) (if ($ counter-> cond! == 2) ($ counter-> wait (); // đợi cái kia bắt đầu trước) for ($ i = 10; $ i thông báo (); if ($ counter-> cond === 2) ($ counter-> cond = 1; $ counter-> wait ();))), $ counter); $ counter-> join (); / * Đầu ra: int (0) int (10) int (1) int (11) int (2) int (12) int (3) int (13) int (4) int (14) int (5) int ( 15) int (6) int (16) int (7) int (17) int (8) int (18) int (9) int (19) * /

Bạn có thể nhận thấy các điều kiện bổ sung đã được đặt xung quanh cuộc gọi tới Threaded :: đợi. Các điều kiện này rất quan trọng vì chúng cho phép gọi lại được đồng bộ hóa tiếp tục khi nó nhận được thông báo và điều kiện được chỉ định là đúng. Điều này rất quan trọng vì thông báo có thể đến từ những nơi khác ngoài lệnh gọi tới Threaded :: thông báo. Do đó, nếu các lệnh gọi đến phương thức Threaded :: wait không được bao gồm trong các điều kiện, chúng tôi sẽ thực hiện cuộc gọi đánh thức giảđiều này sẽ dẫn đến hành vi không thể đoán trước của mã.

Phần kết luận

Chúng tôi đã đề cập đến năm lớp trong gói pthreads (Threaded, Thread, Worker, Volatile và Pool) và cách từng lớp được sử dụng. Chúng tôi cũng đã xem xét khái niệm mới về tính bất biến trong pthreads và làm tổng quan nhanh về các khả năng đồng bộ hóa được hỗ trợ. Với những điều cơ bản này, bây giờ chúng ta có thể bắt đầu xem xét việc sử dụng pthreads trong các trường hợp thế giới thực! Đây sẽ là chủ đề của bài tiếp theo của chúng tôi.

Nếu bạn quan tâm đến bản dịch của bài đăng tiếp theo, hãy cho tôi biết: bình luận trên mạng xã hội. cộng với và chia sẻ bài đăng với đồng nghiệp và bạn bè.

Đôi khi cần thực hiện một số hành động cùng lúc, ví dụ: kiểm tra các thay đổi trong một bảng cơ sở dữ liệu và thực hiện sửa đổi cho một bảng khác. Hơn nữa, nếu một trong các thao tác (ví dụ, kiểm tra các thay đổi) mất nhiều thời gian, thì hiển nhiên việc thực thi tuần tự sẽ không đảm bảo cân bằng tài nguyên.

Để giải quyết loại vấn đề này, lập trình sử dụng đa luồng - mỗi hoạt động được đặt trong một luồng riêng biệt với một lượng tài nguyên chuyên dụng và hoạt động bên trong nó. Với cách tiếp cận này, tất cả các nhiệm vụ sẽ được thực hiện riêng biệt và độc lập.

Mặc dù PHP không hỗ trợ đa luồng, nhưng có một số phương pháp để mô phỏng nó, sẽ được thảo luận bên dưới.

1. Chạy nhiều bản sao của tập lệnh - một bản sao cho hoạt động

//woman.php if (! Isset ($ _ GET ["thread"])) (system ("wget ​​http: //localhost/woman.php? thread = make_me_happy"); system ("wget ​​http: : // localhost / woman.php? thread = make_me_rich ");) elseif ($ _GET [" thread "] ==" make_me_happy ") (make_her_happy ();) elseif ($ _GET [" thread "] ==" make_me_rich ") (find_aosystem_one ();)

Khi chúng tôi thực thi tập lệnh này mà không có tham số, nó sẽ tự động bắt đầu hai bản sao của chính nó, với các ID hoạt động ("thread = make_me_happy" và "thread = make_me_rich"), bắt đầu thực thi các chức năng cần thiết.

Do đó, chúng tôi đạt được kết quả mong muốn - hai hoạt động được thực hiện đồng thời - nhưng tất nhiên đây không phải là đa luồng, mà chỉ là một cái nạng để thực hiện các tác vụ cùng một lúc.

2. Đường dẫn của Jedi - Sử dụng Phần mở rộng PCNTL

PCNTL là một phần mở rộng cho phép bạn làm việc đầy đủ với các quy trình. Ngoài quản lý, nó hỗ trợ nhắn tin, kiểm tra trạng thái và ưu tiên. Đây là tập lệnh trước đó trông giống như khi sử dụng PCNTL:

$ pid = pcntl_fork (); if ($ pid == 0) (make_her_happy ();) elseif ($ pid> 0) ($ pid2 = pcntl_fork (); if ($ pid2 == 0) (find_a Another_one ();))

Nó trông khá khó hiểu, chúng ta hãy xem xét từng dòng một.

Trong dòng đầu tiên, chúng tôi "fork" quy trình hiện tại (fork - sao chép một quy trình từ việc giữ các giá trị của tất cả các biến), chia nó thành hai quy trình (hiện tại và con) chạy song song.

Để hiểu chúng ta đang ở đâu vào thời điểm hiện tại, trong tiến trình con hoặc cha mẹ, hàm pcntl_fork trả về 0 cho con và ID tiến trình cho cha mẹ. Do đó, trong dòng thứ hai, chúng ta nhìn vào $ pid, nếu nó bằng 0, thì chúng ta đang ở trong tiến trình con - chúng ta đang thực hiện hàm, nếu không, chúng ta đang ở cấp cha (dòng 4), sau đó chúng ta tạo một tiến trình khác và thực hiện nhiệm vụ theo cách tương tự.

Quá trình thực thi tập lệnh:

Do đó, script tạo thêm 2 tiến trình con, là các bản sao của nó, chứa các biến giống nhau có cùng giá trị. Và với sự trợ giúp của số nhận dạng được trả về bởi hàm pcntl_fork, chúng tôi được hướng dẫn hiện tại chúng tôi đang ở luồng nào và thực hiện các hành động cần thiết.

Gần đây tôi đã thử pthreads và rất ngạc nhiên - nó là một tiện ích mở rộng bổ sung khả năng làm việc với một số luồng thực trong PHP. Không giả lập, không ảo thuật, không giả mạo - mọi thứ đều là thật.



Tôi đang xem xét một nhiệm vụ như vậy. Có một nhóm các nhiệm vụ cần được hoàn thành nhanh chóng. PHP có các công cụ khác để giải quyết vấn đề này, chúng không được đề cập ở đây, bài viết là về pthreads.



Pthreads là gì

Đó là tất cả! Chà, hầu hết mọi thứ. Trong thực tế, có một cái gì đó có thể làm khó chịu người đọc tò mò. Không có điều nào trong số này hoạt động trong PHP tiêu chuẩn được biên dịch với các tùy chọn mặc định. Để tận hưởng đa luồng, bạn cần bật ZTS (Zend Thread Safety) trong PHP của mình.

Thiết lập PHP

Tiếp theo, PHP với ZTS. Đừng bận tâm đến sự khác biệt lớn về thời gian chạy so với PHP không có ZTS (37,65 so với 265,05 giây), tôi đã không cố gắng đưa cài đặt PHP về một mẫu số chung. Trong trường hợp không có ZTS, tôi đã bật XDebug chẳng hạn.


Như bạn thấy, khi sử dụng 2 luồng, tốc độ thực thi chương trình cao hơn khoảng 1,5 lần so với trường hợp mã tuyến tính. Khi sử dụng 4 chủ đề - 3 lần.


Bạn có thể chú ý rằng mặc dù vi xử lý là 8 nhân nhưng thời gian thực hiện chương trình hầu như không thay đổi nếu sử dụng nhiều hơn 4 luồng. Có vẻ như điều này là do bộ xử lý của tôi có 4 lõi vật lý, để rõ ràng hơn, tôi đã vẽ một tấm ở dạng sơ đồ.


Tóm lược

PHP có thể xử lý đa luồng khá dễ dàng bằng cách sử dụng phần mở rộng pthreads. Điều này làm tăng năng suất một cách hữu hình.

Tags: Thêm thẻ

Thảo luận theo chuỗi

MỘT thảo luận theo chuỗi là một cuộc thảo luận điện tử (chẳng hạn như một cuộc thảo luận qua e-mail, danh sách e-mail, bảng thông báo, nhóm tin hoặc diễn đàn Internet) trong đó phần mềm hỗ trợ người dùng bằng cách nhóm các tin nhắn một cách trực quan. Thông báo thường được nhóm trực quan theo thứ bậc theo chủ đề. Một tập hợp các thông báo được nhóm theo cách này được gọi là chủ đề hoặc đơn giản là "luồng". Diễn đàn thảo luận, ứng dụng e-mail hoặc ứng dụng tin tức được cho là có "chủ đề theo chuỗi" nếu nó nhóm các thư về cùng một chủ đề với nhau để dễ đọc theo cách này. Hơn nữa, các cuộc thảo luận theo chuỗi thường cho phép người dùng trả lời bài đăng cụ thể trong chuỗi của một chủ đề. Do đó, có thể có một hệ thống phân cấp các cuộc thảo luận trong chủ đề đó. Nhiều loại phần mềm khác nhau có thể cho phép hệ thống phân cấp này được hiển thị trong những gì "s được gọi là Chế độ luồng. (Lựa chọn thay thế là Chế độ tuyến tính, thường hiển thị tất cả các bài đăng theo thứ tự ngày tháng, bất kể ai có thể đã trả lời cụ thể cho ai.)

Thuận lợi

Ưu điểm của chế độ xem phân cấp theo luồng là chúng cho phép người đọc đánh giá nhanh cấu trúc tổng thể của một cuộc trò chuyện: cụ thể là ai đang trả lời ai. Vì vậy, nó hữu ích nhất trong tình huống với các cuộc trò chuyện hoặc tranh luận kéo dài, chẳng hạn như nhóm tin: thực sự, đối với các cuộc tranh luận thực sự phức tạp, sẽ nhanh chóng trở nên không thể theo dõi lập luận mà không có một số loại hệ thống phân cấp có sẵn.

Một lợi ích khác là sự đánh giá tinh tế hơn của cộng đồng trong các hệ thống phân cấp theo luồng. Vì phản hồi phải được thực hiện cho các bài đăng cụ thể, chúng cũng được thực hiện cho các cá nhân cụ thể. Do đó, các cuộc trò chuyện theo chuỗi có xu hướng tập trung người viết vào quan điểm và tính cách cụ thể của cá nhân được phản hồi. Điều này ít xảy ra hơn ở các diễn đàn nơi nhận xét mới nhất vừa được chèn vào nhóm chung.

Nhược điểm

Một nhược điểm của việc phân cấp luồng so với luồng phẳng là mức độ phức tạp tăng lên và do đó, chế độ xem như vậy đòi hỏi mức độ thoải mái và tinh tế hơn từ phía người dùng. Do đó, không có gì ngạc nhiên khi sự chiếm dụng của nó là nặng nề nhất ở một số cộng đồng trực tuyến lâu đời nhất và / hoặc phức tạp nhất, chẳng hạn như Usenet, CIX hoặc Slashdot. Nếu so sánh, hệ thống trò chuyện và nhận xét trên web trẻ hơn và mở rộng hơn cho nhiều đối tượng hơn, và do đó, việc phân luồng phân cấp như vậy chỉ mới trở nên phổ biến gần đây trong các đấu trường như vậy.

Việc áp đặt hệ thống phân cấp dạng cây cũng có xu hướng phân tán cuộc thảo luận trong một chủ đề: không còn có thể đăng thông báo phản hồi hoặc tóm tắt một số bài đăng khác nhau trước đó. Thay vào đó, mọi bài đăng trước đó phải được phản hồi riêng lẻ. Có thể cho rằng điều này dẫn đến một phong cách tranh luận đối đầu hơn trong các diễn đàn sử dụng phân luồng phân cấp. Tuy nhiên, điều đó có thể đúng, nếu một câu trả lời theo chuỗi trực tiếp không còn có thể thực hiện được nữa do số lượng câu trả lời cho bài đăng mong muốn, người dùng hiện thường sử dụng các trích dẫn của người mà họ đang trả lời để giữ cho cuộc trò chuyện đi đúng hướng và trôi chảy. thông suốt. Điều này được khuyến nghị bởi hầu hết các cộng đồng bảng tin trong trường hợp luồng đã đạt đến giới hạn toàn diện.

Mở chuỗi

Một chuỗi mở đề cập đến một bài đăng trên blog, nơi người đọc có thể nhận xét và thảo luận về bất kỳ chủ đề nào mà họ chọn. Chúng thường hữu ích hơn trên các blog phổ biến với lượng truy cập lớn; chúng thường được sử dụng khi tác giả của blog không có chủ đề để đăng hoặc khi việc đăng bài tạm dừng.

Chủ đề mở cũng được sử dụng để phá vỡ sự đơn điệu của các bài đăng trên các trang chính của blog. Nhận xét có thể tích tụ trên các bài đăng theo định hướng nội dung; do đó, các tác giả sử dụng các chủ đề mở để thời gian tải trang sẽ không bị chậm lại.

Các ví dụ

* Yahoo! Các nhóm [ http://groups.yahoo.com/], Nhóm MSN [ http://groups.msn.com/] và Slashdot [ http://www.slashdot.com/] tất cả đều cung cấp các diễn đàn dựa trên web có các cuộc thảo luận theo chuỗi.

Xem thêm

* Skywriting học thuật
* Danh sách các điều khoản viết blog

Người giới thiệu

* Dartmouth. (2003). [ http://www.dartmouth.edu/~webteach/articles/discussion.html "Thảo luận trực tuyến" ]
* Wolsey, T. DeVere, [ http://www.readingonline.org/articles/art_index.asp?HREF=wolsey/index.html "Thảo luận văn học trong không gian mạng: Thanh thiếu niên sử dụng các nhóm thảo luận theo chuỗi để nói về sách]. "Đọc trực tuyến", 7 (4), tháng 1 / tháng 2 năm 2004. Truy cập ngày 30 tháng 12 năm 2007

Quỹ Wikimedia. Năm 2010.

  • Leon powe
  • Barh azoum

Xem các từ điển khác:

    Diễn đàn Internet- Gói phần mềm Diễn đàn Internet phpBB, một trong những gói diễn đàn phổ biến nhất ... Wikipedia

    Lịch sử của môi trường học tập ảo những năm 1990- Trong lịch sử của môi trường học tập ảo, những năm 1990 là thời kỳ phát triển, chủ yếu là do sự ra đời của máy tính giá cả phải chăng và Internet. 19901990 * Formal Systems Inc. của Princeton, NJ, Hoa Kỳ giới thiệu Đánh giá dựa trên DOS …… Wikipedia

    Cà phê- Cộng tác Mặt đối mặt (Các) Nhà phát triển Môi trường Giáo dục Liên minh LEAD Bản phát hành ổn định 5.0 / tháng 6 năm 2010 Hệ điều hành Nền tảng chéo… Wikipedia

    Luồng hội thoại- là một tính năng được sử dụng bởi nhiều ứng dụng email, bảng thông báo, nhóm tin hoặc diễn đàn Internet, trong đó phần mềm hỗ trợ người dùng bằng cách nhóm các thư một cách trực quan. Thông báo thường được nhóm trực quan theo thứ bậc theo chủ đề. Một tập hợp các thông báo được nhóm …… Wikipedia

    Slashdot- Ảnh chụp màn hình URL trang chính Slashdot.org Slogan News dành cho dân mọt sách. Nội dung quan trọng ... Wikipedia

    MediaWiki- không gian tên chuyển hướng ở đây. Để được trợ giúp về không gian tên MediaWiki trên Wikipedia, hãy xem Trợ giúp: Không gian tên MediaWiki. Để biết thông tin chung về không gian tên Wikipedia, hãy xem Wikipedia: Không gian tên. Trang thảo luận và trang thảo luận MediaWiki chuyển hướng đến đây. Đối với …… Wikipedia

    Máy tính trung gian giao tiếp- Đối với các mục đích sử dụng khác, xem CMC (định hướng). Giao tiếp qua trung gian máy tính (CMC) được định nghĩa là bất kỳ giao dịch truyền thông nào xảy ra thông qua việc sử dụng hai hoặc nhiều máy tính nối mạng. Trong khi thuật ngữ này thường được dùng để chỉ những ... ... Wikipedia

    So sánh phần mềm wiki- Các bảng sau đây so sánh thông tin chung và thông tin kỹ thuật của một số gói phần mềm wiki. Nội dung 1 Thông tin chung 2 Đối tượng mục tiêu 3 Tính năng 1 4 Tính năng 2… Wikipedia

    Skywriting học thuật- là một thuật ngữ được đặt ra bởi nhà khoa học nhận thức Stevan Harnad mô tả sự kết hợp của nhiều email và một kho lưu trữ web theo chuỗi chủ đề như nhóm tin, danh sách gửi thư điện tử, siêu thư điện tử, netnews hoặc diễn đàn Internet, được liên kết và có thể sắp xếp theo ngày, ... Wikipedia

    Phần mềm ra quyết định cộng tác- Phần mềm ra quyết định cộng tác (CDM) là một ứng dụng hoặc mô-đun phần mềm phối hợp các chức năng và tính năng cần thiết để đưa ra các quyết định tập thể kịp thời, cho phép tất cả các bên liên quan tham gia vào quá trình. Các …… Wikipedia