jjzjj

PHP CLI 进程在退出时永远挂起

coder 2024-04-28 原文

我有一个在命令行上运行的 PHP 脚本,当脚本应该退出时,它却永远挂起。它发生在 Windows 和 Linux 上,因此它与操作系统无关。

我已经尝试使用 XDebug 调试代码,进入最后的 exit 语句(也尝试过 die 但没有成功)。在一些对象上运行了几个析构函数之后,没有什么可以单步执行的了,这个过程只会永远等待。它什么都不做,不消耗任何资源。让进程退出的唯一方法是杀死它,例如 Ctrl+C

在我的所有脚本中都不会发生这种情况,但我有一个可以重现的案例。我不确定它是在我的代码、库代码(主要是 Symfony、Doctrince 等)中还是在 PHP 本身中。

我已经使用 strace 运行脚本,输出的结尾附在下面。我不知道如何调试此输出,但似乎 PHP 正在轮询最后一条语句中的某些内容。

我该如何进一步调试呢?任何帮助将不胜感激。

跟踪输出:

fstat(12, {st_mode=S_IFREG|0777, st_size=1314, ...}) = 0
fstat(12, {st_mode=S_IFREG|0777, st_size=1314, ...}) = 0
fstat(12, {st_mode=S_IFREG|0777, st_size=1314, ...}) = 0
fstat(12, {st_mode=S_IFREG|0777, st_size=1314, ...}) = 0
mmap(NULL, 1314, PROT_READ, MAP_SHARED, 12, 0) = 0x7fb8b969c000
munmap(0x7fb8b969c000, 1314)            = 0
close(12)                               = 0
umask(022)                              = 022
close(3)                                = 0
close(4)                                = 0
write(11, "\1\0\0\0\1", 5)              = 5
shutdown(11, SHUT_RDWR)                 = 0
close(11)                               = 0
write(6, "\1\0\0\0\0\0\0\0", 8)         = 8
close(2)                                = 0
close(1)                                = 0
munmap(0x7fb8b969a000, 4096)            = 0
close(0)                                = 0
munmap(0x7fb8b969b000, 4096)            = 0
munmap(0x7fb8b3191000, 790528)          = 0
munmap(0x7fb8b32d3000, 266240)          = 0
munmap(0x7fb8b3314000, 266240)          = 0
munmap(0x7fb8b3355000, 266240)          = 0
munmap(0x7fb8b3396000, 266240)          = 0
munmap(0x7fb8b33d7000, 266240)          = 0
munmap(0x7fb8b3418000, 266240)          = 0
munmap(0x7fb8b3459000, 266240)          = 0
munmap(0x7fb8b349a000, 266240)          = 0
munmap(0x7fb8b34db000, 266240)          = 0
munmap(0x7fb8b351c000, 266240)          = 0
munmap(0x7fb8b94ba000, 266240)          = 0
write(10, "\1\0\0\0\0\0\0\0", 8)        = 8
poll([{fd=5, events=POLLIN}], 1, 4294967295Process 1358 detached
 <detached ...>

最佳答案

我发现问题与 ZMQ 扩展有关。我的脚本试图向不存在的主机发送消息,即使在我的脚本结束时断开套接字,套接字也一直在等待发送数据。

对于遇到相同问题的任何人,可以通过将套接字上的 \ZMQ::SOCKOPT_LINGER 选项设置为较低的值来解决,例如

<?php

$context = new \ZMQContext(1);
$socket = new \ZMQSocket($context, \ZMQ::SOCKET_PUSH);
$dsn = 'tcp://127.0.0.1:1337';
$socket->connect($dsn);
$socket->send('hi');
echo 'Message sent' . PHP_EOL;

// Without this line, the script will wait forever after the exit statement
$socket->setSockOpt(\ZMQ::SOCKOPT_LINGER, 1000);
$socket->disconnect($dsn);
echo 'Socket disconnected' . PHP_EOL;
exit();

关于PHP CLI 进程在退出时永远挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26884319/

有关PHP CLI 进程在退出时永远挂起的更多相关文章

  1. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  2. ruby - 通过 ruby​​ 进程共享变量 - 2

    我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是

  3. ruby - 通过 RVM 安装 Ruby 1.9.2 永远行不通! - 2

    当我执行>rvminstall1.9.2时一切顺利。然后我做>rvmuse1.9.2也很顺利。但是当涉及到ruby​​-v时..sam@sjones:~$rvminstall1.9.2/home/sam/.rvm/rubies/ruby-1.9.2-p136,thismaytakeawhiledependingonyourcpu(s)...ruby-1.9.2-p136-#fetchingruby-1.9.2-p136-#downloadingruby-1.9.2-p136,thismaytakeawhiledependingonyourconnection...%Total%Rece

  4. ruby - 无法在 Ruby 中将 ffmpeg 作为子进程运行 - 2

    我正在尝试使用以下代码通过将ffmpeg实用程序作为子进程运行并获取其输出并解析它来确定视频分辨率:IO.popen'ffmpeg-i'+path_to_filedo|ffmpegIO|#myparsegoeshereend...但是ffmpeg输出仍然连接到标准输出并且ffmepgIO.readlines是空的。ffmpeg实用程序是否需要一些特殊处理?或者还有其他方法可以获得ffmpeg输出吗?我在WinXP和FedoraLinux下测试了这段代码-结果是一样的。 最佳答案 要跟进mouviciel的评论,您需要使用类似pope

  5. Ruby 守护进程导致 ActiveRecord 记录器 IOError - 2

    我目前正在用Ruby编写一个项目,它使用ActiveRecordgem进行数据库交互,我正在尝试使用ActiveRecord::Base.logger记录所有数据库事件具有以下代码的属性ActiveRecord::Base.logger=Logger.new(File.open('logs/database.log','a'))这适用于迁移等(出于某种原因似乎需要启用日志记录,因为它在禁用时会出现NilClass错误)但是当我尝试运行包含调用ActiveRecord对象的线程守护程序的项目时脚本失败并出现以下错误/System/Library/Frameworks/Ruby.frame

  6. ruby - 在 ruby​​ 中生成一个进程,捕获 stdout,stderr,获取退出状态 - 2

    我想从ruby​​rake脚本运行一个可执行文件,比如foo.exe我希望将foo.exe的STDOUT和STDERR输出直接写入我正在运行rake任务的控制台.当进程完成时,我想将退出代码捕获到一个变量中。我如何实现这一目标?我一直在玩backticks、process.spawn、system但我无法获得我想要的所有行为,只有部分更新:我在Windows上,在标准命令提示符下,而不是cygwin 最佳答案 system获取您想要的STDOUT行为。它还返回true作为零退出代码,这可能很有用。$?填充了有关最后一次system调

  7. ruby-on-rails - 如何用不同的用户运行nginx主进程 - 2

    A/ctohttp://wiki.nginx.org/CoreModule#usermaster进程曾经以root用户运行,是否可以以不同的用户运行nginxmaster进程? 最佳答案 只需以非root身份运行init脚本(即/etc/init.d/nginxstart),就可以用不同的用户运行nginxmaster进程。如果这真的是你想要做的,你将需要确保日志和pid目录(通常是/var/log/nginx&/var/run/nginx.pid)对该用户是可写的,并且您所有的listen调用都是针对大于1024的端口(因为绑定(

  8. Ruby 守护进程和 JRuby - 备选方案 - 2

    我有一个应用程序正在从Ruby迁移到JRuby(由于需要通过Java提供更好的Web服务安全支持)。我使用的gem之一是daemons创建后台作业。问题在于它使用fork+exec来创建后台进程,但这对JRuby来说是禁忌。那么-是否有用于创建后台作业的替代gem/wrapper?我目前的想法是只从shell脚本调用rake并让rake任务永远运行......提前致谢,克里斯。更新我们目前正在使用几个与Java线程相关的包装器,即https://github.com/jmettraux/rufus-scheduler和https://github.com/philostler/acts

  9. ruby-on-rails - Rails - Carrierwave 进程抛出 ArgumentError : no images in this image list - 2

    在尝试实现应用auto_orient的过程之后!对于我的图片,我收到此错误:ArgumentError(noimagesinthisimagelist):app/uploaders/image_uploader.rb:36:in`fix_exif_rotation'app/controllers/posts_controller.rb:12:in`create'Carrierwave在没有进程的情况下工作正常,但在添加进程后尝试上传图像时抛出错误。流程如下:process:fix_exif_rotationdeffix_exif_rotationmanipulate!do|image|

  10. ruby-on-rails - Ruby 长时间运行的进程对队列事件使用react - 2

    我有一个将某些事件写入队列的Rails3应用。现在我想在服务器上创建一个服务,每x秒轮询一次队列,并按计划执行其他任务。除了创建ruby​​脚本并通过cron作业运行它之外,还有其他稳定的替代方案吗? 最佳答案 尽管启动基于Rails的持久任务是一种选择,但您可能希望查看更有序的系统,例如delayed_job或Starling管理您的工作量。我建议不要在cron中运行某些东西,因为启动整个Rails堆栈的开销可能很大。每隔几秒运行一次它是不切实际的,因为Rails上的启动时间通常为5-15秒,具体取决于您的硬件。不过,每天这样做几

随机推荐