【发布时间】:2016-12-15 05:46:52
【问题描述】:
我有一个作为守护进程运行的 perl 脚本。它每 10 秒访问一次数据库,如果队列中有任何作业,它会生成一个单独的 shell 来执行单个作业。但是脚本经常无法从数据库中获取作业。
理想情况下,应该像这样调用 DB
read(3, "\3def\3job\rqueueb\7JobTy"..., 55) = 55
read(3, ";\0\0\6", 4) = 4
下面是这个守护进程/进程的 strace。是在等什么吗?感谢您的帮助。
pipe([6, 7]) = 0
pipe([8, 9]) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0) = 31858
close(9) = 0
close(7) = 0
read(8, "", 4) = 0
close(8) = 0
fcntl64(6, F_GETFL) = 0 (flags O_RDONLY)
fstat64(6, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xfffffffff7783000
_llseek(6, 0, 0xffd4e540, SEEK_CUR) = -1 ESPIPE (Illegal seek)
fstat64(6, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
read(6, "", 4096) = 0
close(6) = 0
munmap(0xf7783000, 4096) = 0
rt_sigaction(SIGHUP, {SIG_IGN, [], 0}, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGINT, {SIG_IGN, [], 0}, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGQUIT, {SIG_IGN, [], 0}, {SIG_DFL, [], 0}, 8) = 0
waitpid(31858, 0xffd4e670, 0) = -1 ECHILD (No child processes)
rt_sigaction(SIGHUP, {SIG_DFL, [], 0}, NULL, 8) = 0
rt_sigaction(SIGINT, {SIG_DFL, [], 0}, NULL, 8) = 0
rt_sigaction(SIGQUIT, {SIG_DFL, [], 0}, NULL, 8) = 0
这会立即重复(至少)两次。
【问题讨论】:
-
我认为没有源代码的 strace 没有任何价值。再说一次,如果来源是 Perl,我怀疑 strace 是否会有所帮助。您需要在调试器中运行您的 Perl 并设置一个断点,在该断点处检测到没有可用的作业,并等到它在您知道作业可用的情况下触发。然后查看程序的变量以了解发生了什么。
-
或者,在您认为有用的地方添加打印语句的 Perl 脚本。或者,在此处发布脚本 - 简化为仍然存在该问题的最小版本。这(strace)对于不了解您的脚本的人几乎没有用处。
-
_llseek 似乎是个嫌疑犯。需要查看脚本以了解发生了什么。
-
我怀疑 llseek 是个问题。它寻求当前位置,可能是为了清除缓冲区,但我敢打赌它在管道上失败并不重要。
标签: linux database perl shell strace