PHP có phân luồng không?


130

Tôi tìm thấy gói PECL này được gọi là chủ đề , nhưng vẫn chưa có bản phát hành. Và không có gì đang đến trên trang web PHP.


Bất cứ ai cũng biết nếu cái này ( pcntl_fork()) sẽ hoạt động nếu được gọi từ Apache?
Josh K

Điều này là vô cùng cũ, nhưng tôi có một câu trả lời thực sự cung cấp luồng trong php (xem bên dưới để biết các liên kết).
Hẻm núi Alec

Họ khuyên không nên gọi fork từ môi trường máy chủ. Tôi không trách họ. Tuy nhiên, pcntl_fork dường như là giải pháp tốt nhất để phân luồng PHP.
just_wes

Có, bạn không cần phải xử lý một quá trình php apache2.
andho

2
Sử dụng pthreads hoạt động như bùa mê
Baba

Câu trả lời:


40

Không có gì có sẵn mà tôi biết. Điều tốt nhất tiếp theo sẽ chỉ đơn giản là có một tập lệnh thực thi một tập lệnh khác thông qua CLI, nhưng điều đó hơi thô sơ. Tùy thuộc vào những gì bạn đang cố gắng làm và mức độ phức tạp của nó, điều này có thể hoặc không thể là một lựa chọn.


1
Đó là những gì tôi nghĩ. Tôi thấy một loạt các bài đăng cũ hơn nói không, và không có gì trên php.net, vì vậy đây là suy nghĩ của tôi. Cảm ơn đã xác nhận nó.
Thomas Owens

2
Vâng, gói PECL đó là một loại trêu chọc - tôi cũng đã chạy qua nó nhưng không có gì đã đến từ nó.
Wilco

180

Từ hướng dẫn PHP cho phần mở rộng pthreads :

pthreads là một API hướng đối tượng cho phép đa luồng người dùng trong PHP. Nó bao gồm tất cả các công cụ bạn cần để tạo các ứng dụng đa luồng được nhắm mục tiêu trên Web hoặc Bảng điều khiển. Các ứng dụng PHP có thể tạo, đọc, viết, thực thi và đồng bộ hóa với Chủ đề, Công nhân và Stackables.

Không thể tin được như âm thanh này, nó hoàn toàn đúng. Ngày nay, PHP có thể đa luồng cho những ai muốn thử nó.

Bản phát hành đầu tiên của PHP4, ngày 22 tháng 5 năm 2000, PHP được cung cấp với kiến ​​trúc an toàn luồng - một cách để nó thực thi nhiều phiên bản của trình thông dịch của nó trong các luồng riêng biệt trong môi trường SAPI (API máy chủ) đa luồng. Trong 13 năm qua, thiết kế của kiến ​​trúc này đã được duy trì và nâng cao: Nó đã được sử dụng trên các trang web lớn nhất thế giới kể từ đó.

Luồng trong đất người dùng chưa bao giờ là một mối quan tâm đối với nhóm PHP và nó vẫn còn như ngày nay. Bạn nên hiểu rằng trong thế giới mà PHP kinh doanh, đã có một phương pháp xác định tỷ lệ - thêm phần cứng. Trong nhiều năm, PHP đã tồn tại, phần cứng ngày càng rẻ hơn và do đó, điều này ngày càng trở thành mối quan tâm của nhóm PHP. Trong khi nó ngày càng rẻ hơn, nó cũng mạnh hơn nhiều; ngày nay, điện thoại di động và máy tính bảng của chúng tôi có kiến ​​trúc lõi kép và lõi tứ và rất nhiều RAM đi kèm, máy tính để bàn và máy chủ của chúng tôi thường có 8 hoặc 16 lõi, RAM 16 và 32 gigabyte, mặc dù chúng tôi không phải lúc nào cũng có thể có hai trong ngân sách và có hai máy tính để bàn hiếm khi hữu ích cho hầu hết chúng ta.

Ngoài ra, PHP được viết cho người không lập trình, đó là ngôn ngữ bản địa của nhiều người có sở thích. Lý do PHP rất dễ được chấp nhận là vì nó là một ngôn ngữ dễ học và viết. Lý do PHP rất đáng tin cậy ngày nay là vì khối lượng công việc khổng lồ đi vào thiết kế của nó và mọi quyết định của nhóm PHP đưa ra. Đó là độ tin cậy và sự tuyệt vời tuyệt đối giữ nó trong ánh sáng, sau tất cả những năm này; nơi mà các đối thủ của nó đã rơi vào thời gian hoặc áp lực.

Lập trình đa luồng không dễ dàng đối với hầu hết, ngay cả với API mạch lạc và đáng tin cậy nhất, có nhiều điều khác nhau để suy nghĩ và nhiều quan niệm sai lầm. Nhóm PHP không mong muốn đa luồng đất của người dùng là một tính năng cốt lõi, nó chưa bao giờ được quan tâm nghiêm túc - và đúng như vậy. PHP không nên phức tạp, cho tất cả mọi người.

Tất cả mọi thứ được xem xét, vẫn có những lợi ích cần có từ việc cho phép PHP sử dụng các tính năng đã sẵn sàng và được thử nghiệm để cho phép một phương tiện tận dụng tối đa những gì chúng ta có, khi thêm nhiều hơn không phải luôn là một lựa chọn và rất nhiều nhiệm vụ là không bao giờ thực sự cần thiết.

pthreads đạt được, đối với những người muốn khám phá nó, một API cho phép người dùng sử dụng các ứng dụng PHP đa luồng. API của nó rất là một công việc đang tiến triển và được chỉ định mức độ ổn định và hoàn thiện beta.

Một kiến ​​thức phổ biến là một số thư viện mà PHP sử dụng không phải là luồng an toàn, nên rõ ràng với lập trình viên rằng pthreads không thể thay đổi điều này và không cố gắng thử. Tuy nhiên, bất kỳ thư viện nào là an toàn luồng đều có thể sử dụng được, như trong bất kỳ cài đặt an toàn luồng nào khác của trình thông dịch.

pthreads sử dụng Posix Themes (ngay cả trong Windows), những gì lập trình viên tạo ra là các luồng thực thi thực sự, nhưng để các luồng đó hữu ích, họ phải biết về PHP - có thể thực thi mã người dùng, chia sẻ biến và cho phép một phương tiện giao tiếp hữu ích (đồng bộ hóa). Vì vậy, mọi luồng được tạo bằng một phiên bản của trình thông dịch, nhưng theo thiết kế, trình thông dịch của nó được cách ly với tất cả các phiên bản khác của trình thông dịch - giống như các môi trường API máy chủ đa luồng. pthreads cố gắng thu hẹp khoảng cách một cách lành mạnh và an toàn. Nhiều mối quan tâm của lập trình viên các luồng trong C chỉ dành cho lập trình viên của pthreads, theo thiết kế, pthreads được sao chép khi đọc và sao chép trên ghi (RAM là rẻ), vì vậy không có trường hợp nào xử lý cùng một dữ liệu vật lý , nhưng cả hai đều có thể ảnh hưởng đến dữ liệu trong một luồng khác.

Tại sao sao chép trên đọc và sao chép trên viết:

public function run() {
    ...
    (1) $this->data = $data;
    ...
    (2) $this->other = someOperation($this->data);
    ...
}

(3) echo preg_match($pattern, $replace, $thread->data);

(1) Trong khi khóa đọc và ghi được lưu trữ trên kho lưu trữ dữ liệu đối tượng pthreads, dữ liệu được sao chép từ vị trí ban đầu của nó trong bộ nhớ vào kho lưu trữ đối tượng. pthreads không điều chỉnh số lần đếm của biến, Zend có thể giải phóng dữ liệu gốc nếu không có thêm tài liệu tham khảo nào về nó.

(2) Đối số của someOperation tham chiếu kho đối tượng, dữ liệu gốc được lưu trữ, bản thân nó là bản sao kết quả của (1), được sao chép lại cho động cơ vào thùng chứa zval, trong khi điều này xảy ra khóa đọc được giữ kho đối tượng, khóa được giải phóng và động cơ có thể thực hiện chức năng. Khi zval được tạo, nó có số đếm bằng 0, cho phép động cơ giải phóng bản sao khi hoàn thành thao tác, vì không có tham chiếu nào khác đến nó.

(3) Đối số cuối cùng với preg_match tham chiếu đến kho lưu trữ dữ liệu, khóa đọc được lấy, dữ liệu được đặt trong (1) được sao chép thành zval, một lần nữa với số lần đếm là 0. Khóa được giải phóng, Cuộc gọi đến preg_match hoạt động trên một bản sao của dữ liệu, bản thân nó là bản sao của dữ liệu gốc.

Những điều cần biết:

  • Bảng băm của cửa hàng đối tượng nơi lưu trữ dữ liệu, luồng an toàn,
    dựa trên TsHashTable được phân phối với PHP, bởi Zend.

  • Kho đối tượng có khóa đọc và ghi, khóa truy cập bổ sung được cung cấp cho TsHashTable sao cho nếu cần (và nó, var_dump / print_r, truy cập trực tiếp vào các thuộc tính khi công cụ PHP muốn tham chiếu chúng) pthread có thể điều khiển TsHashTable bên ngoài API được xác định.

  • Các khóa chỉ được giữ trong khi các hoạt động sao chép xảy ra, khi các bản sao đã được tạo ra các khóa được phát hành, theo một thứ tự hợp lý.

Điều này có nghĩa là:

  • Khi xảy ra ghi, không chỉ có khóa đọc và ghi, mà còn có khóa truy cập bổ sung. Bảng đã bị khóa, không có cách nào bối cảnh khác có thể khóa, đọc, viết hoặc ảnh hưởng đến nó.

  • Khi xảy ra đọc, không chỉ khóa đọc được giữ mà cả khóa truy cập bổ sung, một lần nữa bảng bị khóa.

Không có hai bối cảnh có thể truy cập vật lý hoặc đồng thời cùng một dữ liệu từ kho lưu trữ đối tượng, nhưng việc ghi được thực hiện trong bất kỳ bối cảnh nào có tham chiếu sẽ ảnh hưởng đến dữ liệu được đọc trong bất kỳ bối cảnh nào có tham chiếu.

Điều này được chia sẻ không có kiến ​​trúc và cách duy nhất để tồn tại là cùng tồn tại. Những người hiểu biết một chút sẽ thấy rằng, có rất nhiều bản sao đang diễn ra ở đây, và họ sẽ tự hỏi liệu đó có phải là một điều tốt. Khá nhiều sao chép diễn ra trong một thời gian chạy động, đó là động lực của một ngôn ngữ động. pthreads được triển khai ở cấp độ của đối tượng, bởi vì có thể đạt được sự kiểm soát tốt đối với một đối tượng, nhưng các phương thức - mã mà lập trình viên thực thi - có bối cảnh khác, không bị khóa và sao chép - phạm vi phương thức cục bộ. Phạm vi đối tượng trong trường hợp đối tượng pthreads nên được coi là một cách để chia sẻ dữ liệu giữa các bối cảnh, đó là mục đích của nó. Với suy nghĩ này, bạn có thể áp dụng các kỹ thuật để tránh khóa cửa hàng đối tượng trừ khi cần thiết,

Hầu hết các thư viện và tiện ích mở rộng có sẵn cho PHP là các trình bao bọc mỏng xung quanh bên thứ 3, chức năng cốt lõi của PHP ở một mức độ là điều tương tự. pthreads không phải là một trình bao bọc mỏng xung quanh Chủ đề Posix; nó là một API luồng dựa trên chủ đề Posix. Không có điểm nào trong việc triển khai Chủ đề trong PHP mà người dùng không hiểu hoặc không thể sử dụng. Không có lý do gì mà một người không có kiến ​​thức về mutex là gì hoặc không nên tận dụng tất cả những gì họ có, cả về kỹ năng và tài nguyên. Một đối tượng hoạt động giống như một đối tượng, nhưng bất cứ nơi nào hai bối cảnh sẽ va chạm, pthread cung cấp sự ổn định và an toàn.

Bất cứ ai từng làm việc trong java đều sẽ thấy sự tương đồng giữa một đối tượng pthreads và luồng trong java, những người đó sẽ không nghi ngờ gì khi thấy một lỗi gọi là ConcảnModificationException - vì nó phát ra lỗi do thời gian chạy java nếu hai luồng ghi cùng một dữ liệu vật lý kiêm nhiệm. Tôi hiểu tại sao nó tồn tại, nhưng nó gây trở ngại cho tôi rằng với tài nguyên rẻ như chúng, cùng với thực tế thời gian chạy có thể phát hiện đồng thời chính xác và chỉ có thể đạt được sự an toàn cho người dùng, mà nó chọn đưa ra một lỗi có thể gây tử vong trong thời gian chạy hơn là quản lý việc thực thi và truy cập dữ liệu.

Không có lỗi ngu ngốc như vậy sẽ được phát ra bởi pthreads, API được viết để làm cho luồng ổn định và tương thích nhất có thể, tôi tin.

Đa luồng không giống như sử dụng cơ sở dữ liệu mới, cần chú ý chặt chẽ đến từng từ trong hướng dẫn và các ví dụ được gửi với pthreads.

Cuối cùng, từ hướng dẫn PHP:

pthreads đã và đang là một thử nghiệm có kết quả khá tốt. Bất kỳ hạn chế hoặc tính năng nào của nó có thể thay đổi bất cứ lúc nào; đó là bản chất của thí nghiệm. Đó là những hạn chế - thường được áp đặt bởi việc thực hiện - tồn tại vì lý do chính đáng; Mục đích của pthreads là cung cấp một giải pháp có thể sử dụng cho đa tác vụ trong PHP ở mọi cấp độ. Trong môi trường mà pthreads thực thi, một số hạn chế và giới hạn là cần thiết để cung cấp một môi trường ổn định.


14
Utter vô nghĩa.
Joe Watkins

7
@GeoC. Tôi thậm chí không chắc quan điểm của bạn ở đây là gì, đó chỉ là một sự vô nghĩa và bạn không đưa ra lý do , logic hay nói cách khác, về lý do tại sao bạn không đồng ý với bất kỳ đối số nào (trong đó tôi thực sự không thể thấy bất kỳ lý lẽ nào trong bài đăng) .
Jimbo

13
@Tudor Tôi không nghĩ bạn thực sự biết bạn đang nói về cái gì, vì vậy tôi rất vui khi bỏ qua bạn.
Joe Watkins

4
@Tudor - nhiều nhà khoa học đã không "nhìn thấy điểm" của một cái gì đó mới trong chi nhánh của họ, hoặc một cái gì đó hữu ích. Lịch sử đã chỉ ra rằng thường xuyên hơn không, những người như bạn chỉ đơn giản là sai, đó là sự thật. Giống như thực tế là tất cả mọi thứ bạn viết ở đây là, thiếu một từ tốt hơn, phân. Tôi đề nghị, với tất cả mọi thứ trong tâm trí tích cực, không tham gia vào các chủ đề mà bạn không biết gì về điều này (đây là một).
NB

12
Điều buồn cười. Joe Watkins là tác giả của pthreads, và Tudor vẫn cố gắng chứng minh anh ta sai.
Hristo Valkanov

48

Dưới đây là một ví dụ về những gì Wilco đề xuất:

$cmd = 'nohup nice -n 10 /usr/bin/php -c /path/to/php.ini -f /path/to/php/file.php action=generate var1_id=23 var2_id=35 gen_id=535 > /path/to/log/file.log & echo $!';
$pid = shell_exec($cmd);

Về cơ bản, điều này thực thi tập lệnh PHP tại dòng lệnh, nhưng ngay lập tức trả về PID và sau đó chạy trong nền. (Tiếng vang $! Đảm bảo không có gì khác được trả về ngoài PID.) Điều này cho phép tập lệnh PHP của bạn tiếp tục hoặc thoát nếu bạn muốn. Khi tôi đã sử dụng điều này, tôi đã chuyển hướng người dùng sang một trang khác, trong đó cứ sau 5 đến 60 giây, một cuộc gọi AJAX được thực hiện để kiểm tra xem báo cáo có còn chạy không. (Tôi có một bảng để lưu trữ gen_id và người dùng liên quan đến nó.) Tập lệnh kiểm tra chạy như sau:

exec('ps ' . $pid , $processState);
if (count($processState) < 2) {
     // less than 2 rows in the ps, therefore report is complete
}

Có một bài viết ngắn về kỹ thuật này ở đây: http://nsaunders.wordpress.com/2007/01/12/rasty-a-background- process-in-php /


Tôi có một vấn đề nhỏ, làm thế nào để bạn kiểm tra trạng thái của quá trình nền? bạn có thể soi sáng cho tôi không
slier 24/11/13

25

Tóm lại: có, có đa luồng trong php nhưng thay vào đó bạn nên sử dụng đa xử lý.

Thông tin Backgroud: chủ đề so với quy trình

Luôn có một chút nhầm lẫn về sự khác biệt của các luồng và các tiến trình, vì vậy tôi sẽ mô tả ngắn gọn cả hai:

  • Một luồng là một chuỗi các lệnh mà CPU sẽ xử lý. Dữ liệu duy nhất nó bao gồm là một bộ đếm chương trình. Mỗi lõi CPU sẽ chỉ xử lý một luồng tại một thời điểm nhưng có thể chuyển đổi giữa việc thực hiện các luồng khác nhau thông qua lập lịch.
  • Một quy trình là một tập hợp các tài nguyên được chia sẻ. Điều đó có nghĩa là nó bao gồm một phần của bộ nhớ, các biến, thể hiện đối tượng, xử lý tệp, mutexes, kết nối cơ sở dữ liệu, v.v. Mỗi quá trình cũng chứa một hoặc nhiều chủ đề. Tất cả các luồng của cùng một quá trình chia sẻ tài nguyên của nó, vì vậy bạn có thể sử dụng một biến trong một luồng mà bạn đã tạo trong một luồng khác. Nếu các luồng đó là một phần của hai quá trình khác nhau, thì chúng không thể truy cập trực tiếp vào các tài nguyên khác. Trong trường hợp này, bạn cần liên lạc giữa các quá trình thông qua ví dụ: ống, tệp, ổ cắm ...

Đa xử lý

Bạn có thể đạt được tính toán song song bằng cách tạo các quy trình mới (cũng chứa một luồng mới) với php. Nếu các chủ đề của bạn không cần nhiều giao tiếp hoặc đồng bộ hóa, đây là lựa chọn của bạn, vì các quy trình bị cô lập và không thể can thiệp vào công việc của nhau. Ngay cả khi một người gặp sự cố, điều đó không liên quan đến những người khác. Nếu bạn cần giao tiếp nhiều, bạn nên đọc tiếp tại "đa luồng" hoặc - thật đáng buồn - xem xét sử dụng ngôn ngữ lập trình khác, bởi vì giao tiếp và đồng bộ hóa giữa các quá trình giới thiệu rất nhiều phức tạp.

Trong php bạn có hai cách để tạo một quy trình mới:

hãy để hệ điều hành làm điều đó cho bạn : bạn có thể nói với hệ điều hành của bạn để tạo một quy trình mới và chạy một tập lệnh php mới (hoặc tương tự) trong đó.

  • đối với linux, bạn có thể sử dụng cách sau hoặc xem xét câu trả lời của Darryl Hein :

    $cmd = 'nice php script.php 2>&1 & echo $!';
    pclose(popen($cmd, 'r'));
  • Đối với cửa sổ, bạn có thể sử dụng điều này:

    $cmd = 'start "processname" /MIN /belownormal cmd /c "script.php 2>&1"';
    pclose(popen($cmd, 'r'));

tự làm điều đó với một ngã ba : php cũng cung cấp khả năng sử dụng forking thông qua hàm pcntl_fork () . Một hướng dẫn tốt về cách làm điều này có thể được tìm thấy ở đây nhưng tôi thực sự khuyên bạn không nên sử dụng nó, vì ngã ba là một tội ác chống lại loài người và đặc biệt là chống lại oop.

Đa luồng

Với đa luồng, tất cả các chủ đề của bạn chia sẻ tài nguyên của họ để bạn có thể dễ dàng liên lạc giữa và đồng bộ hóa chúng mà không cần nhiều chi phí. Mặt khác, bạn phải biết những gì bạn đang làm, vì điều kiện chủng tộc và bế tắc rất dễ sản xuất nhưng rất khó để gỡ lỗi.

Php tiêu chuẩn không cung cấp bất kỳ đa luồng nào nhưng có một phần mở rộng (thử nghiệm) thực sự làm - pthreads . Tài liệu api của nó thậm chí đã đưa nó vào php.net . Với nó, bạn có thể làm một số thứ như bạn có thể làm bằng các ngôn ngữ lập trình thực :-) như thế này:

class MyThread extends Thread {
    public function run(){
        //do something time consuming
    }
}

$t = new MyThread();
if($t->start()){
    while($t->isRunning()){
        echo ".";
        usleep(100);
    }
    $t->join();
}

Đối với linux, có một hướng dẫn cài đặt ngay tại stackoverflow's.

Đối với các cửa sổ hiện có một:

  • Trước tiên, bạn cần phiên bản chủ đề an toàn của php.
  • Bạn cần các phiên bản được biên dịch sẵn của cả pthread và phần mở rộng php của nó. Chúng có thể được tải xuống ở đây . Đảm bảo rằng bạn tải xuống phiên bản tương thích với phiên bản php của bạn.
  • Sao chép php_pthreads.dll (từ mã zip bạn vừa tải xuống) vào thư mục tiện ích mở rộng php của bạn ([phpDirectory] / ext).
  • Sao chép pthreadVC2.dll vào [phpDirectory] (thư mục gốc - không phải thư mục tiện ích mở rộng).
  • Chỉnh sửa [phpDirectory] /php.ini và chèn dòng sau

    extension=php_pthreads.dll
  • Kiểm tra nó với kịch bản ở trên với một số giấc ngủ hoặc một cái gì đó ngay tại đó nhận xét.

Và bây giờ là BUT lớn : Mặc dù điều này thực sự hoạt động, php ban đầu không được tạo ra để đa luồng. Có tồn tại phiên bản php an toàn luồng và kể từ phiên bản 5.4, nó dường như gần như không có lỗi nhưng sử dụng php trong môi trường đa luồng vẫn không được khuyến khích trong hướng dẫn sử dụng php (nhưng có lẽ họ chỉ không cập nhật hướng dẫn của họ trên này, chưa). Một vấn đề lớn hơn nhiều có thể là rất nhiều tiện ích mở rộng phổ biến không an toàn cho chuỗi . Vì vậy, bạn có thể nhận được các chủ đề với tiện ích mở rộng php này nhưng các chức năng mà bạn phụ thuộc vẫn không an toàn cho chủ đề, do đó bạn có thể sẽ gặp phải các điều kiện chủng tộc, bế tắc, v.v. trong mã mà bạn không tự viết ...


5
Điều đó là sai lầm khủng khiếp, bài viết mà bạn tham chiếu là từ năm 2008. Nếu PHP không xử lý luồng an toàn ở cốt lõi thì nó sẽ không có các mô-đun SAPI.
Joe Watkins

1
@Joe: Được rồi, tôi đã thay đổi nó trong lõi là an toàn chủ đề nhưng rất nhiều phần mở rộng không có.
Francois Bourgeois

1
Rất nhiều ? Tôi nghĩ rằng bạn sẽ tìm thấy nó rất ít, bạn đã tìm thấy tài liệu nhưng không đọc đúng: Lưu ý: Những người được đánh dấu * không phải là thư viện an toàn luồng và không nên sử dụng với PHP làm mô-đun máy chủ trong đa máy chủ web Windows đã đọc (IIS, Netscape). Điều này không quan trọng trong môi trường Unix.
Joe Watkins

6
PHP rất an toàn cho luồng, và đã được nhiều năm, một số thư viện bên ngoài và một vài thư viện được đóng gói thì không, nhưng dù sao nó cũng được ghi chép lại và khá rõ ràng. pthreads tạo ra các luồng an toàn như các luồng được tạo bởi zend trong một sapi đa luồng, tôi biết điều này, bởi vì tôi, một mình, đã viết pthreads. Nó sử dụng mọi API có sẵn được trình bày bởi PHP giống như API của máy chủ, tôi không nói nó hoàn toàn ổn định, nhưng hình ảnh bạn đã vẽ hoàn toàn sai và thông tin rất kém.
Joe Watkins

@Joe: Khi hướng dẫn sử dụng nói rằng điều này không quan trọng đối với môi trường Unix, họ đang đề cập đến thực tế là trên hệ thống Unix apache sử dụng nhiều quy trình và trên Windows, nó sử dụng các luồng. Vì vậy, về cơ bản họ đang nói "nếu bạn không sử dụng chủ đề nào, bạn không phải lo lắng về các tiện ích mở rộng không an toàn cho chuỗi." Khi chúng ta sử dụng các luồng với pthread, tất nhiên - nó cũng quan trọng đối với môi trường Unix.
Francois Bourgeois

17

Bạn có thể sử dụng pcntl_fork () để đạt được một cái gì đó tương tự như các chủ đề. Về mặt kỹ thuật, nó là các quy trình riêng biệt, vì vậy việc giao tiếp giữa hai bên không đơn giản với các luồng và tôi tin rằng nó sẽ không hoạt động nếu PHP được gọi bằng apache.


4
Tôi đang sử dụng thành công pcntl_fork để song song hóa một tác vụ nhập dữ liệu khá lớn. Hoạt động tuyệt vời, và tôi đã làm cho nó hoạt động trong khoảng một giờ. Có một chút của một đường cong học tập, nhưng một khi bạn hiểu những gì đang diễn ra, nó khá dễ dàng.
Nông dân Frank

Frank, đó là với CLI php hay PHP apache?
Artem Russakovskii

@Artem: Tôi cũng muốn biết.
Josh K

5
@Frank Nông dân đang trêu chọc chúng tôi ... giống như gói PECL.
Roger

1
Tôi đã sử dụng pcntl_fork với CLI. Tôi chưa bao giờ thử nó trong apache; Nghe có vẻ rủi ro. Ngay cả trên CLI, đã có một số vấn đề bất ngờ. Tôi dường như gặp vấn đề khi một đứa trẻ đóng tay cầm cơ sở dữ liệu (vì nó đã hoàn thành công việc), nó cũng đóng kết nối cho anh chị em. Vì trẻ em là bản sao của cha mẹ, chuẩn bị cho sự kỳ quặc. Kể từ đó, tôi đã thiết kế lại mã của mình để đơn giản tạo ra các quy trình mới, tách biệt hoàn toàn thông qua exec () - nó sạch hơn theo cách đó.
Nông dân Frank


7

pcntl_fork()là những gì bạn đang tìm kiếm, nhưng quá trình của nó không được phân luồng. do đó bạn sẽ có vấn đề trao đổi dữ liệu. để giải quyết chúng, bạn có thể sử dụng các hàm phaph semaphore ( http://www.php.net/manual/de/ref.sem.php ) hàng đợi tin nhắn có thể dễ dàng hơn một chút so với phân đoạn bộ nhớ dùng chung.

Dù sao, một chiến lược tôi đang sử dụng trong một khung web mà tôi đang phát triển để tải các khối tài nguyên chuyên sâu của một trang web (có thể có các yêu cầu bên ngoài) song song: tôi đang thực hiện một hàng đợi công việc để biết dữ liệu nào tôi đang chờ đợi và sau đó tôi rẽ nhánh tắt công việc cho mọi quy trình. Sau khi hoàn thành, họ lưu trữ dữ liệu của họ trong bộ đệm apc dưới một khóa duy nhất mà tiến trình cha có thể truy cập. một khi mọi dữ liệu ở đó nó tiếp tục. Tôi đang sử dụng đơn giản usleep()để chờ đợi vì giao tiếp giữa các quá trình không thể thực hiện được trong apache (trẻ em sẽ mất kết nối với cha mẹ và trở thành zombie ...). Vì vậy, điều này đưa tôi đến điều cuối cùng: điều quan trọng là tự giết mọi đứa trẻ! cũng có các lớp xử lý rẽ nhánh nhưng vẫn giữ dữ liệu, tôi đã không kiểm tra chúng nhưng khung zend có một lớp và chúng thường làm mã chậm nhưng đáng tin cậy. bạn có thể tìm thấy nó ở đây: http://zendframework.com/manual/1.9/en/zendx.console. Process.unix.overview.html tôi nghĩ rằng họ sử dụng các phân đoạn shm! cuối cùng nhưng không kém phần quan trọng là có một lỗi trên trang web zend này, một lỗi nhỏ trong ví dụ.

while ($process1->isRunning() && $process2->isRunning()) {
    sleep(1);
}
should of course be:
while ($process1->isRunning() || $process2->isRunning()) {
    sleep(1);
}



5

Tôi có một lớp luồng PHP đang hoạt động hoàn hảo trong môi trường sản xuất trong hơn hai năm nay.

EDIT: Điều này hiện có sẵn như là một thư viện soạn nhạc và là một phần của khung MVC của tôi, Hazaar MVC.

Xem: https://git.hazaarlabs.com/hazaar/hazaar-thread


Điều gì xảy ra nếu, theo ví dụ của bạn, chương trình trong file.php, chẳng hạn, chẳng hạn như nó tồn tại một danh sách uris của trang web 10k và sau đó phải lưu kết quả vào tệp CSV ... Liệu tệp này có phải là một tệp không vấn đề?
Roger

Quá trình phụ sẽ chạy cùng một người dùng với tập lệnh máy chủ / máy chủ web. Vì vậy, khi viết tập tin, bạn sẽ có những cân nhắc tương tự về quyền như bạn thường làm. Nếu bạn gặp vấn đề với việc ghi tập tin, hãy thử ghi vào / tmp và khi nó hoạt động, hãy đi từ đó.
Jamie Carl

1
Liên kết hiện đã chết do thiết kế lại, bạn có thể tải nó trên máy quay lại tại đây: web.archive.org/web/20130922043615/http://dev.funkynerd.com/
Tony

Đã thêm vào khung MVC của tôi bây giờ. Xem: git.hazaarlabs.com/hazaar/hazaar-thread
Jamie Carl


1

Đã từng nghe về appserver techdivision chưa?

Nó được viết bằng php và hoạt động như một máy chủ ứng dụng quản lý đa luồng cho các ứng dụng php có lưu lượng truy cập cao. Vẫn đang trong giai đoạn thử nghiệm nhưng rất hứa hẹn.


-3

Có một tính năng khá mơ hồ và sẽ sớm bị phản đối, được gọi là tick . Điều duy nhất tôi từng sử dụng nó là cho phép một tập lệnh bắt SIGKILL (Ctrl + C) và đóng lại một cách duyên dáng.


3
Bọ ve không thực hiện song song. Về cơ bản, sau mỗi câu lệnh, hàm tick của bạn sẽ chạy. Trong khi chức năng đánh dấu của bạn đang chạy, mã chính không chạy.
Nông dân Frank

1
tick chỉ cần thiết cho bộ xử lý signal ().
Nick
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.