perl语言中 fork()、exec()、waitpid() 、 $? >> 8 组合

perl语言中 fork、exec、waitpid 、 $? >> 8 组合

fork()

描述:
使用fork()系统调用派生一个新进程。任何共享的套接字或文件句柄都会在进程之间复制。您必须确保等待您的子进程,以防止形成“僵尸”进程。
也就是,fork()函数通过系统调用创建一个与原来进程(父进程)几乎完全相同的进程;这两个进程做完全相同的事。
说明:
子进程是父进程的副本,它将获得父进程数据空间、堆、栈等资源的副本。
注意,子进程持有的是上述存储空间的“副本”,这意味着父子进程不共享这些存储空间。
linux将复制父进程的地址空间内容给子进程,因此,子进程由了独立的地址空间。
返回值:
如果fork进程失败,将返回undef; 如果成功,将返回子进程ID为父进程; 如果成功,将返回子进程ID。

示例:

 $pid = fork();
if( $pid == 0 ) {
   print "This is child process\n";
   print "Child process is existing\n";
   exit 0;
}
print "This is parent process and child ID is $pid\n";
print "Parent process is existing\n";
exit 0;

结果:

This is parent process and child ID is 19678
Parent process is existing
This is child process
Child process is existing

exec()

fork后的子进程中使用exec函数族,可以装入和运行其它程序(子进程替换原有进程,和父进程做不同的事)。
exec函数族可以根据指定的文件名或目录名找到可执行文件,并用它来取代原调用进程的数据段、代码段和堆栈段。在执行完后,原调用进程的内容除了进程号外,其它全部被新程序的内容替换了。另外,这里的可执行文件既可以是二进制文件,也可以是Linux下任何可执行脚本文件。

在Linux中使用exec函数族主要有一下两种情况:
当进程认为自己不能再为系统和用户做出任何贡献时,就可以调用任何exec函数族让自己重生;
如果一个进程想执行另外一个程序,那么它就可以调用fork函数新建一个进程,然后调用任何一个exec函数使子进程重生;

waitpid()

**僵尸进程:**当子进程退出时,父进程还没有(使用wait或waitpid)接收其退出状态时,子进程就成了僵尸进程
**孤儿进程:**当子进程还在运行时,父进程先退出了,子进程就会成为孤儿进程被pid=1的init/systemd进程收养

需要说明的是,僵尸进程的父进程死掉后,僵尸进程也会被pid=1的init/systemd进程收养,而init/systemd进程会定期清理其下僵尸进程,并在它的任意子进程退出时检查它的领土下是否有僵尸进程存在,从而保证init/systemd下不会有太多僵尸进程

$? >> 8

$? 上一次管道关闭,反勾号(``)命令或者 waitwaitpid,或者 system 函数 返回的状态。
请注意它不仅仅是简单的退出代码,而是由下层的 wait(2) 或者 waitpid(2) 系统调用返回的完整的 16 位状态。
因此,子过程的退出值在高位,也就是 $? >> 8

组合使用

Log::Log4perl::init(\q(
    log4perl.rootLogger = INFO, Screen
    log4perl.appender.Screen = Log::Log4perl::Appender::Screen
    log4perl.appender.Screen.layout = PatternLayout
    log4perl.appender.Screen.layout.ConversionPattern = %d - %H - %F:%L - %p - %m{chomp}%n
));
my $logger = Log::Log4perl->get_logger();

my $pid = fork();
if ($pid == 0){
	exec($cmd_line);
}
system("echo $pid > ${work_dir}/pid.txt");
waitpid($pid, 0);
my $status = $? >> 8;
$logger->info(" finished and exit code is: $status");

参考

https://www.jc2182.com/perl/perl-fork-func.html
https://blog.csdn.net/holden_liu/article/details/100174792
https://blog.csdn.net/zjwson/article/details/53337212

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值