本文来源于阿里云-云栖社区,原文点击这里。
近期在给一个客户编写数据库迁移工具,语言使用的是不太熟悉的perl。而需要做进程间通信源自这样一个需求,即并行迁移,想要真正的提升性能,我没有选择多线程的方式,而是直接选择多进程。
而我们都知道,多进程和多线程的区别就在于多进程的稳定性,多进程的内存资源是独立的,而多线程确实和父进程共享的。场景图示如下,
linux下的进程间通信,共有三个媒介,消息队列、共享内存段以及信号量。通常共享内存段和信号量配合使用,而这里我们只需要做简单的 持锁+计数+释锁,这么说来,此场景下信号量就是个天然的计数器了。
这三种媒介可以使用ipcs命令查看,
使用
如下代码示例,
#!/usr/bin/perl
use IPC::SysV qw(S_IRWXU IPC_CREAT);
use IPC::Semaphore;
my $sem0;
my $sem1;
my @childs;
my $sem = IPC::Semaphore->new(1556, 1, S_IRWXU|IPC_CREAT)
|| die "IPC::Semaphore->new: $!\n";
##创建一个信号量集,1556是key,1是信号量的个数,S_IRWXU即700权限,IPC_CREAT没有则创建
$sem->setval(0,0);
##设置初始值,这里只有一个信号量则下标为0,初始值为0
for ($i=0; $i<5; $i++){
if($pid=fork())
{
$childs[$i] = $pid;
}elsif(defined $pid){
sleep(1);
$sem->op(0, +1, SEM_UNDO);
##op方法通过semop来调用系统PV原子操作,子进程退出时会通过 SEM_UNDO 来解锁
exit;
}else{
print "Error!\n";
exit;
}
}
for $p (@childs){
waitpid($p, 0);
}
$sem1 = $sem->getval(0);
##获取信号量值
print $sem1."\n";
其中涉及到的几个常用方法如下,
相关文章推荐