Trong trường hợp đó, khóa có bao giờ được hệ điều hành phát hành không?
Liệu nó có thấy "này, tập lệnh lấy khóa bị rơi" và nhả khóa không?
Nó có khóa ngay lập tức không?
Tất cả các câu hỏi này phụ thuộc vào hệ thống. Perl 5 không thực hiện chức năng khóa tệp, nó chỉ cung cấp giao diện chung cho các khóa flock(2)
, fcntl(2)
hoặc lockf(3)
(tùy thuộc vào những gì có sẵn trong hệ điều hành). Cũng có thể có sự khác biệt giữa những gì xảy ra khi một chương trình thoát, phân đoạn hoặc bị giết bằng một sigkill.
Xét nghiệm nhanh dưới Linux cho thấy một khóa được lấy ra trong điều kiện thoát bình thường:
$ perl -le 'open my $fh, ">", "f" or die $!; print flock($fh, 6) ? "got lock" : "was already locked", "\n"'
got lock
$ perl -le 'open my $fh, ">", "f" or die $!; print flock($fh, 6) ? "got lock" : "was already locked", "\n"'
got lock
Hãy xem những gì sẽ xảy ra khi chúng ta die
:
$ perl -le 'open my $fh, ">", "f" or die $!; print flock($fh, 6) ? "got lock" : "was already locked", "\n"; die "died"'
got lock
died at -e line 1.
$ perl -le 'open my $fh, ">", "f" or die $!; print flock($fh, 6) ? "got lock" : "was already locked", "\n"; die "died"'
got lock
died at -e line 1.
Để có được một segfault, chúng tôi sẽ cần truy cập vào C, tôi đang sử dụng Inline
để tải xuống:
$ cat segfault.pl
#!/usr/bin/perl
use strict;
use warnings;
use Inline "C";
open my $fh, ">", "f" or die $!;
print flock($fh, 6) ? "got lock" : "was already locked", "\n";
crash();
__DATA__
__C__
void crash() {
int* ptr = NULL;
*ptr = 5;
}
$ perl segfault.pl
got lock
Segmentation fault
$ perl segfault.pl
got lock
Segmentation fault
Và cuối cùng, đây là những gì sẽ xảy ra khi một chương trình được gửi SIGKILL
:
$ cat fork.pl
#!/usr/bin/perl
use strict;
use warnings;
$SIG{CHLD} = "IGNORE"; #auto-reap children
die "could not fork: $!" unless defined(my $pid = fork);
unless ($pid) {
#child
open my $fh, ">", "f" or die $!;
print flock($fh, 6) ? "got lock" : "was already locked", "\n";
sleep(100);
exit;
}
kill 9, $pid;
die "could not fork: $!" unless defined($pid = fork);
unless ($pid) {
#child
open my $fh, ">", "f" or die $!;
print flock($fh, 6) ? "got lock" : "was already locked", "\n";
exit;
}
$ perl fork.pl
got lock
got lock
Từ những thí nghiệm này, chúng ta có thể thấy rằng các khóa được phát hành trong Linux cho từng trường hợp, bạn đã quan tâm.
Ngoài ra, có một trường hợp perl đang chạy cho từng tập lệnh hay không, sao cho tập lệnh đó bị lỗi/dừng mà không giải phóng khóa?
Có, Perl 5 có một quá trình perl
cho mỗi tập lệnh. Ngay cả khi bạn ngã ba, đứa trẻ có quy trình riêng của mình là perl
. Luồng không cung cấp quy trình perl
riêng biệt.
Lưu ý: nếu quy trình gốc được khóa và không cho khóa trước khi khóa, thì trẻ sẽ có cùng khóa ngay cả khi cha mẹ thoát.
câu trả lời chi tiết tuyệt vời, cảm ơn bạn rất nhiều! cũng nhờ soulSurfer2010 cho câu trả lời ngắn nhưng vẫn chính xác và mang tính thông tin! –