linux - Perl 线程——它们可以被唯一命名吗?(Linux)
问题描述
从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
command ,似乎无法获得修改后的线程名称。它只显示最后一个触及 $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
获胜者 usingtop -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
在此处添加 Ikegami 代码的修改版本以供查看此页面的其他人将来参考,另存为 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;
推荐阅读
- python - 如何将 JSON/XML/YAML 数据读入 Sphinx RST 文件以编程方式生成文档页面?
- android - Flutter 项目中的任务“:app:processDebugResources”执行失败
- leaflet.markercluster - 如何将markercluster与已经聚集的数据一起使用?
- python - for循环中的os.system taskkill
- python - 我在为 Django 中的特定页面设置默认 URL 时遇到了一些问题
- text - 使用 sed 删除文本文件最后一行中的新行
- flutter - 运行我的颤振应用程序时终端中的消息
- python - 使用shutil和pandas df生成文件
- python - 找不到模块“libmultinest.dll”(或其依赖项之一)。尝试使用带有构造函数语法的完整路径
- macos - 将 zsh 提示更改为仅两个文件夹