如何调试await multi Promise时会被系统杀死的脚本?
答案 “脚本使用了太多内存”。
我启动了一些start
来逐行读取文本文件,并将文本转换为blob,然后将其发送到套接字:
use experimental :pack;
sub heart-msg(Str $msg, Str $device-id --> Blob) {
my $heart-msg = $msg.substr(0, $msg.chars - 8);
my $header-buf = pack("H*", $heart-msg);
my $device-id-buf = pack("L*", $device-id);
$header-buf ~ $device-id-buf
}
sub deal-message(Str $msg, Str $device-id --> Blob) {
my $now = DateTime.now();
my $year = $now.year;
my $month = $now.month;
my $day = $now.day;
my $hour = $now.hour;
my $minute = $now.minute;
my $second = $now.second.Int;
my $check-number = 0;
my $head-msg = $msg.substr(0,4);
my $device-id-length = $msg.substr(4,2);
my $pf-code = $msg.substr(14, 2);
my $msg-length = $msg.substr(16, 4);
my $rel-time = $msg.substr(20, 4);
my $end-msg = $msg.substr(38, $msg.chars - 38 - 2);
my $head-msg-buf = pack("H*", $head-msg);
my $device-id-len-buf = pack("H*", $device-id-length);
my $device-id-buf = pack("L*", $device-id);
my $pf-code-buf = pack("H*", $pf-code);
my $msg-length-buf = pack("H*", $msg-length);
my $rel-time-buf = pack("H*", $rel-time);
my $year-buf = pack("S*", $year);
my $month-buf = pack("C*", $month);
my $day-buf = pack("C*", $day);
my $hour-buf = pack("C*", $hour);
my $minute-buf = pack("C*", $minute);
my $second-buf = pack("C*", $second);
my $end-msg-buf = pack("H*", $end-msg);
my @bufs = [$device-id-len-buf, $device-id-buf, $pf-code-buf, $msg-length-buf,
$rel-time-buf, $year-buf, $month-buf, $day-buf, $hour-buf, $minute-buf, $second-buf,
$end-msg-buf];
for @bufs -> $byte {
my $byte_sum = [+] $byte.contents;
$check-number += $byte_sum;
}
$check-number = $check-number % 256;
my $checked-msg-buf = pack("C*", $check-number);
[~] $head-msg-buf, |@bufs, $checked-msg-buf
}
sub deal-data(Str $msg, Str $device-id --> Blob) {
my $header = $msg.substr(0, 4);
given $header {
when '6868' {
return deal-message($msg, $device-id);
}
when '7468' {
return heart-msg($msg, $device-id);
}
default { return Buf.new }
}
}
sub MAIN(
:$host = '10.0.0.77',
Int() :$port = 4444,
Rat() :$interval = 0.001,
:$file = 'data.txt',
Int() :$device-num = 169) {
my $conn = IO::Socket::INET.new(:$host, :$port);
my @devices = "modelId.txt".IO.lines;
my @promises = gather for @devices[159..$device-num] -> $device-id {
take start {
my $f = lazy $file.IO.lines;
my $iterator = $f.iterator;
react {
whenever Supply.interval($interval) {
try {
my $line := $iterator.pull-one;
if $line =:= IterationEnd {
done;
} else {
my $blob = deal-data($line.chomp.split(/\s+/).tail, $device-id.Str);
#say $blob;
$conn.write($blob);
}
}
QUIT {
$conn.close;
say 'connecting closed';
default {
say .^name, '→ ', .Str;
say "handled in line $?LINE";
}
}
LAST {
say "Connection closed";
done;
}
}
}
}
}
await @promises;
}
在CentOS 7.4(12核,32G RAM)上运行时,几秒钟后,我的脚本被系统杀死了。在Win11(12核,16G RAM)上运行时,没问题。
那么如何调试这个脚本呢?
Answer "the script used too much memory".
I start a few start
to read text file line by line, and convert the text to blob, then send it to socket:
use experimental :pack;
sub heart-msg(Str $msg, Str $device-id --> Blob) {
my $heart-msg = $msg.substr(0, $msg.chars - 8);
my $header-buf = pack("H*", $heart-msg);
my $device-id-buf = pack("L*", $device-id);
$header-buf ~ $device-id-buf
}
sub deal-message(Str $msg, Str $device-id --> Blob) {
my $now = DateTime.now();
my $year = $now.year;
my $month = $now.month;
my $day = $now.day;
my $hour = $now.hour;
my $minute = $now.minute;
my $second = $now.second.Int;
my $check-number = 0;
my $head-msg = $msg.substr(0,4);
my $device-id-length = $msg.substr(4,2);
my $pf-code = $msg.substr(14, 2);
my $msg-length = $msg.substr(16, 4);
my $rel-time = $msg.substr(20, 4);
my $end-msg = $msg.substr(38, $msg.chars - 38 - 2);
my $head-msg-buf = pack("H*", $head-msg);
my $device-id-len-buf = pack("H*", $device-id-length);
my $device-id-buf = pack("L*", $device-id);
my $pf-code-buf = pack("H*", $pf-code);
my $msg-length-buf = pack("H*", $msg-length);
my $rel-time-buf = pack("H*", $rel-time);
my $year-buf = pack("S*", $year);
my $month-buf = pack("C*", $month);
my $day-buf = pack("C*", $day);
my $hour-buf = pack("C*", $hour);
my $minute-buf = pack("C*", $minute);
my $second-buf = pack("C*", $second);
my $end-msg-buf = pack("H*", $end-msg);
my @bufs = [$device-id-len-buf, $device-id-buf, $pf-code-buf, $msg-length-buf,
$rel-time-buf, $year-buf, $month-buf, $day-buf, $hour-buf, $minute-buf, $second-buf,
$end-msg-buf];
for @bufs -> $byte {
my $byte_sum = [+] $byte.contents;
$check-number += $byte_sum;
}
$check-number = $check-number % 256;
my $checked-msg-buf = pack("C*", $check-number);
[~] $head-msg-buf, |@bufs, $checked-msg-buf
}
sub deal-data(Str $msg, Str $device-id --> Blob) {
my $header = $msg.substr(0, 4);
given $header {
when '6868' {
return deal-message($msg, $device-id);
}
when '7468' {
return heart-msg($msg, $device-id);
}
default { return Buf.new }
}
}
sub MAIN(
:$host = '10.0.0.77',
Int() :$port = 4444,
Rat() :$interval = 0.001,
:$file = 'data.txt',
Int() :$device-num = 169) {
my $conn = IO::Socket::INET.new(:$host, :$port);
my @devices = "modelId.txt".IO.lines;
my @promises = gather for @devices[159..$device-num] -> $device-id {
take start {
my $f = lazy $file.IO.lines;
my $iterator = $f.iterator;
react {
whenever Supply.interval($interval) {
try {
my $line := $iterator.pull-one;
if $line =:= IterationEnd {
done;
} else {
my $blob = deal-data($line.chomp.split(/\s+/).tail, $device-id.Str);
#say $blob;
$conn.write($blob);
}
}
QUIT {
$conn.close;
say 'connecting closed';
default {
say .^name, '→ ', .Str;
say "handled in line $?LINE";
}
}
LAST {
say "Connection closed";
done;
}
}
}
}
}
await @promises;
}
When running on CentOS 7.4(12 core, 32G RAM), after a few seconds, my script was killed by system. When running on Win11(12 core, 16G RAM), it's OK.
So how to debug this script?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论