Đây là một lời khuyên khá phức tạp, nhưng nó chắc chắn sẽ làm được những gì bạn muốn, nếu bạn sẵn sàng sửa đổi và biên dịch lại PHP.
Hãy xem mã nguồn PHP tại https:// github.com/php/php-src/blob/master/Zend/zend_execute_API.c
(tệp là Zend/zend_execute_API.c
), tại hàm zend_set_timeout
. Đây là chức năng thực hiện giới hạn thời gian. Đây là cách nó hoạt động trên các nền tảng khác nhau:
-
trên Windows, tạo một chuỗi mới, bắt đầu hẹn giờ trên đó và khi quá trình kết thúc, hãy đặt một biến chung có tên là
timed_out
đến 1, lõi thực thi PHP kiểm tra biến này cho mọi lệnh, sau đó thoát (rất đơn giản) -
trên Cygwin, hãy sử dụng itimer với ITIMER_REAL, đo lường thực thời gian, bao gồm bất kỳ giấc ngủ nào, chờ đợi, bất kỳ điều gì, sau đó giơ tín hiệu điều đó sẽ làm gián đoạn bất kỳ xử lý và ngừng xử lý
-
trên các hệ thống unix khác, hãy sử dụng itimer với ITIMER_PROF, chỉ đo thời gian CPU dành cho quy trình hiện tại (nhưng cả ở chế độ người dùng và chế độ hạt nhân). Điều này có nghĩa là việc chờ đợi các quy trình khác (như MySQL) không được tính vào điều này.
Bây giờ những gì bạn muốn làm là thay đổi itimer trên Linux của bạn từ ITIMER_PROF thành ITIMER_REAL, tất nhiên bạn cần phải làm thủ công, biên dịch lại, cài đặt, v.v. Sự khác biệt khác giữa hai điều này là chúng cũng sử dụng tín hiệu khác nhau khi bộ đếm thời gian chạy ngoài. Vì vậy, đề xuất của tôi là thay đổi ifdef:
# ifdef __CYGWIN__
thành
# if 1
để bạn đặt cả ITIMER_REAL và tín hiệu mà PHP chờ đợi thành SIGALRM.
Dù sao thì toàn bộ ý tưởng này vẫn chưa được thử nghiệm (tôi sử dụng nó cho một số hệ thống rất cụ thể, nơi ITIMER_PROF bị hỏng và có vẻ như để làm việc), không được hỗ trợ, v.v. Sử dụng nó và tự chịu rủi ro. Nó có thể hoạt động với chính PHP, nhưng nó có thể phá vỡ các mô-đun khác, trong PHP và trong Apache, nếu họ vì bất kỳ lý do gì, hãy sử dụng tín hiệu SIGALRM hoặc bộ đếm thời gian khác.