引用Perlvar:
在多线程脚本中,Perl 协调线程,以便任何线程都可以修改其 $0 的副本,并且更改对 ps(1( 可见(假设操作系统一起播放(。请注意,其他线程的 $0 视图不会改变,因为它们有自己的副本。
我似乎没有这种行为。相反,$0 似乎由我的所有线程共享,并且在 ps 输出中,顶级主 perl 解释器的 cmdline 正在修改为最后一个线程应用的最终值。
例如。 我的目标是不让所有线程在 COMMAND 列下命名相同:
top -b -n 1 -H -p 223860
top - 17:54:56 up 73 days, 2:15, 7 users, load average: 0.23, 0.70, 0.92
Threads: 22 total, 0 running, 22 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 32358832 total, 26418060 free, 1090028 used, 4850744 buff/cache
KiB Swap: 16777212 total, 16149116 free, 628096 used. 30804716 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
223860 app_sy+ 20 0 3833640 166216 2500 S 0.0 0.5 0:45.75 tool_reader.
223863 app_sy+ 20 0 3833640 166216 2500 S 0.0 0.5 0:03.88 tool_reader.
223864 app_sy+ 20 0 3833640 166216 2500 S 0.0 0.5 0:04.67 tool_reader.
223865 app_sy+ 20 0 3833640 166216 2500 S 0.0 0.5 0:00.00 tool_reader.
223867 app_sy+ 20 0 3833640 166216 2500 S 0.0 0.5 0:34.62 tool_reader.
223868 app_sy+ 20 0 3833640 166216 2500 S 0.0 0.5 0:03.85 tool_reader.
223869 app_sy+ 20 0 3833640 166216 2500 S 0.0 0.5 0:04.41 tool_reader.
223870 app_sy+ 20 0 3833640 166216 2500 S 0.0 0.5 0:00.00 tool_reader.
223872 app_sy+ 20 0 3833640 166216 2500 S 0.0 0.5 0:40.14 tool_reader.
在这样的命令列下有更有用的东西,并且主线程保持不变。
|
|
|
v
top -b -n 1 -H -p 223860
top - 17:54:56 up 73 days, 2:15, 7 users, load average: 0.23, 0.70, 0.92
Threads: 22 total, 0 running, 22 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 32358832 total, 26418060 free, 1090028 used, 4850744 buff/cache
KiB Swap: 16777212 total, 16149116 free, 628096 used. 30804716 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
223860 app_sy+ 20 0 3833640 166216 2500 S 0.0 0.5 0:45.75 tool_reader.
223863 app_sy+ 20 0 3833640 166216 2500 S 0.0 0.5 0:03.88 syncer
223864 app_sy+ 20 0 3833640 166216 2500 S 0.0 0.5 0:04.67 partition1
223865 app_sy+ 20 0 3833640 166216 2500 S 0.0 0.5 0:00.00 partition2
223867 app_sy+ 20 0 3833640 166216 2500 S 0.0 0.5 0:34.62 partition3
223868 app_sy+ 20 0 3833640 166216 2500 S 0.0 0.5 0:03.85 input_merger1
223869 app_sy+ 20 0 3833640 166216 2500 S 0.0 0.5 0:04.41 input_merger2
223870 app_sy+ 20 0 3833640 166216 2500 S 0.0 0.5 0:00.00 input_merger3
有谁知道这是怎么做到的?我现在正在使用一个相当旧的perl,版本5.16.3,以防这是一个错误?
更新 2020-10-21:我刚刚发现了一种更好的方法来实现这一目标 - 实际的 linux 系统调用。 https://man7.org/linux/man-pages/man2/prctl.2.html
Troels Liebe Bentsen 慷慨地贡献了一个模块来巧妙地处理这个问题。 https://metacpan.org/pod/Sys::Prctl
远比摆弄 0 美元!!无缝
原始帖子内容在下面继续....
ps -T -p 126193
PID SPID TTY TIME CMD
126193 126193 pts/11 00:00:00 test2.pl
126193 126194 pts/11 00:00:00 __thr1 #<--- now unique
126193 126195 pts/11 00:00:00 __thr2 #<--- now unique
top -H -p 126193
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
126193 xxxxxxx+ 20 0 305948 7972 2244 S 0.0 0.0 0:00.01 test2.pl
126194 xxxxxxx+ 20 0 305948 7972 2244 S 0.0 0.0 0:00.00 __thr1
126195 xxxxxxx+ 20 0 305948 7972 2244 S 0.0 0.0 0:00.00 __thr2
####
多亏了@ikegami,我找到了一个可行的解决方案。
为了使子线程保持活动状态,需要进行一些小的更改,并且还需要阻止主线程将它们重新连接起来。(根据它的行为方式,我假设如果子线程到达它们生成的子线程的末尾,它们将被完全终止,Linux 会清理它们 - 即使主线程尚未调用它们join
。
对于将来阅读此页面的任何其他人,我很想知道为什么pstree,ps和top中的每一个都显示不同的结果。
无论如何,将此信息和比较留在这里,以防对其他人有所帮助。
最终结果:
- 使用
ps
命令,似乎无法获取线程的修改名称。它仅显示触及 $0 的最后一个线程将其设置为的字符串 - 同样,使用 pstree
pstree -p -a -l 144741
也只显示主线程作为每个子线程的名称,并且不显示有关线程所做的更改的任何内容。 - 但是,非常幸运的是,使用顶级作品!!!
top -H -b -p 180547
,它清楚地显示了主线程,以及所有子线程,它们使用 $0 设置的名称
来自ps的例子:
app_sy+ 180547 131203 180547 0 3 18:08 pts/1 00:00:00 thr2
app_sy+ 180547 131203 180548 0 3 18:08 pts/1 00:00:00 thr2
app_sy+ 180547 131203 180549 0 3 18:08 pts/1 00:00:00 thr2
使用 pstree 的示例:
test.pl,180547
|-{test.pl},180548
`-{test.pl},180549
获胜者使用top -n 1 -H -b -p 180547
,它显示了每个线程成功应用于 $0 的不同名称!!!!!
top - 18:00:08 up 69 days, 8:53, 3 users, load average: 4.10, 3.95, 4.05
Threads: 3 total, 0 running, 3 sleeping, 0 stopped, 0 zombie
%Cpu(s): 7.7 us, 33.5 sy, 0.0 ni, 58.8 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 13144056+total, 1351640 free, 45880316 used, 84208608 buff/cache
KiB Swap: 16777212 total, 16777212 free, 0 used. 78196224 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
180547 app_+ 20 0 299572 7152 2144 S 0.0 0.0 0:00.00 test.pl
180548 app_+ 20 0 299572 7152 2144 S 0.0 0.0 0:00.02 thr1
180549 app_+ 20 0 299572 7152 2144 S 0.0 0.0 0:00.01 thr2
在此处添加池上代码的修改版本,供查看此页面的其他人将来参考,保存为 test.pl:
#!/usr/bin/perl
use strict;
use warnings;
use feature qw( say );
use threads;
use threads::shared;
my $phase :shared = 0;
my $main_pid = $$;
sub advance {
lock $phase;
++$phase;
cond_signal($phase);
}
sub wait_for {
lock $phase;
cond_wait($phase) while $phase != $_[0];
}
sub advance_and_wait_for {
lock $phase;
++$phase;
cond_signal($phase);
cond_wait($phase) while $phase != $_[0];
}
my $thr1 = async {
my $id = 'thr1';
wait_for(0);
advance_and_wait_for(2);
say "[$id] Setting $0 to $id.";
$0 = $id;
say "[$id] $0 = $0";
print `ps -eLf|grep $main_pid` =~ s/^/[$id] /mrg;
advance_and_wait_for(4);
say "[$id] $0 = $0";
advance();
while(1){
sleep 1;
}
};
my $thr2 = async {
my $id = 'thr2';
wait_for(1);
advance_and_wait_for(3);
say "[$id] $0 = $0";
say "[$id] Setting $0 to $id.";
$0 = $id;
say "[$id] $0 = $0";
print `ps -eLf| grep $main_pid` =~ s/^/[$id] /mrg;
advance();
while(1){
sleep 1;
}
};
sleep 5;
print "Main thread pid is $main_pid - and $0 is ($0)n";
my $waitfor = <STDIN>;
$_->join for $thr1, $thr2;